Create Static Libraries using GCC

Static libraries provide a mechanism by which we can “pack” object code into reusable libraries. In this article I’m going to focus on creating static libraries of C (and C++) objects and functions. Let’s get started.

Creating a static library is actually a very easy process that consists in just two simple steps:

  1. Compiling source code into object code.
  2. Archiving all the generated object code into a single file that represents the library.

Assume we have the following C source files that declare a 3-element vector type and a dot function that calculates the dot product among two vectors:

We can use the following two commands to create a static library:

Please notice we have named our static library “libalgebra.a”. This is not just a random choice as a static library’s name must begin with “lib” and end with “.a” in order to be able to have GCC link new programs against it.

Now that our library is ready, we can redistribute it with the header file “algebra.h” so other programmers can use it in their applications.

In order to illustrate this point further, let’s write a simple C program that includes the header and links against our library:

In the above example you can notice how we can liberally use data types and functions declared in our library as if they where part of this very same program.

Now, in order to compile, all we need is the “algebra.h” header, however, in order to have this program link, we have to use the “-l” (lowercase L) flag of the GCC compiler to specify our shared library, like so:

Given the “-lalgebra” flag, GCC will look for a file called “libalgebra.a” (hence the importance in the library’s naming convention). The “-L” flag tells GCC where this file is located.

Posted in C++

On Polymorphism in C++

C++, as many other Object-Oriented languagues, provides many facilities for us to implement our Object Oriented Designs.

In this post I talk about a feature which is not frequently discussed, but must be taken into account when implementing a class hierarchy that leverages polymorphism as part of its design.

Let’s suppose we have a base class (conveniently named “Base”) and a derived class (conveniently called “Derived”) that extends “Base” through Public Inheritance.

If you don’t know what “Public Inheritance” means, all you really need to know for the purpose of this article is that there are three different kinds of inheritance in C++: public, protected and private. Public Inheritance is akin to inheritance in other programming languages such as Java, Python, Objective-C and C#.

Going back to our example, I’ve coded the Base and Derived classes’ interfaces in the following snippet:

Now, for the implementation, I want to have every object whose class is derived from “Base” to have its classname printed upon creation. So, what I am going to do is add a call to printClassName() in Base’s constructor.

This is the program entry point:

If you know your Patterns, by now you’ll probably have noticed by now that this example is just an implementation of the Factory Method pattern, where I’m relying in a virtual method for leveraging derived-class-specific behavior in the Base class.

The problem here is that, when we try to compile this program, we get the following error:

GCC is warning us that there is no implementation for the abstract method “printClassName” in class “Base”, and it aborts!

Why does this happen? The compiler certainly should not be trying to find an implementation for an abstract method after all. The reason this happens is because of how inheritance works in C++.

When an object whose class is derived from another class is instantiated, what happens in C++ is that, in order to create this object, an inner instance of its base class is created first. In our example, when calling Derived’s constructor, Base’s constructor is called first.

This actually implies that the derived object does not exist until the the inner base object is created.

In turn, this means that the derived object’s vtable (used for implementing Polymorphism in C++) does not exist when the base class’ constructor is executing, so the compiler assumes that the base class’ implementation of the method has to be invoked, and that triggers the link error.

Even worse would be the case if the method was not abstract (but still virtual). In this case the program would build fine, but, at runtime you would find out that the base class’ implementation is being called instead of the derived class’.

How can you fix this problem?

Fortunately, the solution is simple, all you have to do is adopt the following gold rule:

Never call virtual methods on a partially-created object.

In order to fix our program, what I’m going to do first is to remove the printClassName call from Base’s constructor.

So, where should I place it now? Well, depending on the application it could be someplace or another. Since I would not like to change my design, what I’m going to do here is to separate the object construction into two phases: construction and initialization.

Construction will be carried out by the constructors, and initialization will be carried out by a special init() method that we can call once all the base objects have been created.

This separation will allow us to work safely, as all constructors will have executed when init() is called.

Applying these changes, the program will now look like this: the header for the Base class will include a new init() method:

And the base class’ implementation will implement init() as to call our virtual method:

At this point the program should build fine and, when run, should produce the following result:

As a final note, it would be possible to hide the call to init() into the Derived class’ constructor, but this will only work as long as Derived is the last class is the hierarchy.

As soon as we add a “Derived2” class that inherits from Derived, we will have to refactor the call to init() into Derived2’s constructor, and so forth.

It would be interesting to see whether this problem arises in other programming languages. This will be left as an exercise for the reader.

You can find more information on abstract (pure virtual) methods and problems related to them here.

Posted in C++