ritter
ritter

Reputation: 7699

How can the order of include statements matter in the linking step?

I cannot explain the behaviour I am seeing when linking my code. Maybe someone has an idea what's going on...

I have a multiple file C++ project which uses GNU automake tools as its build system (all on Linux).

After adding a source and header file (lets call them util.cc and util.h) to the project and having an already existing source file (calc.cc) calling a function from the newly added files I get a linking error depending on where the include statement appears. I repeat: The error occurs in the linking step, compilation runs fine!!

Example:

I get an error when putting the new include statement at the end of the preexisting statements, like:

calc.cc:

#include "file1.h"
#include "file2.h"
#include "file3.h"
#include "file4.h"
#include "util.h"   // new header

This version compiles fine. But linking produces an error (symbol not found)!!

Now, when changing this to

#include "util.h"   // new header
#include "file1.h"
#include "file2.h"
#include "file3.h"
#include "file4.h"

then compilation and linking runs fine!

Since the linker only reads the .o files, this must mean that different content is produced depending on where the include statement appears. How can this be?

Compiler is g++ (GCC) 4.4.6

Upvotes: 2

Views: 570

Answers (3)

user529758
user529758

Reputation:

You're absolutley right: different object code is produced in the two cases. As @hmjd also points out, most likely there's a macro in util.h which one of the other (.h or .c) files use, and any undeclared, called identifier is assumed to be a function by the compiler -- this is most likely the error here.

Upvotes: 0

janneb
janneb

Reputation: 37198

Simple, header files can (re)define macros which can change the interpretation of later macros.

For instance, in your example above, if file1.h does

#define lseek lseek64

and util.h has an inline function which calls lseek, then depending on the include order the generated object code will have a symbol reference to lseek or lseek64.

Which is why projects tend to have rules that config.h (generated by autoconf) is included first.

Upvotes: 1

Tom Tanner
Tom Tanner

Reputation: 9354

Chances are that util.h has a #define that changes the behaviour of one of the other files.

Your best chance of working out exactly what is going on would involve examining those header files for the name of the missing symbol and getting the pre-processor output from compiling calc.cc both 'working' and 'non working' way, and comparing the two files.

Upvotes: 1

Related Questions