Define and declare

There’s a difference between defining an object and declaring it. First, multiple declaration is ok, but multiple definition leads to compilation error.

We declare a function by omitting their bodies like:

int function(int a, int b);

And declare+define it including their bodies:

int function(int a, int b){
    return a+b;
}

As stated before, multiple declaration is allowed, thus the following code is correct:

#include <cstdio>
int f();
int f();
int f(){
    return 1;
}
int main (){
    printf("%d\n", f());
    return 0;
}

With variables it’s quite different since they don’t have body. The way to declare a variable without defining it consists in prefixing it with the keyword extern:

extern int x;

And to declare+define it, we do the old way:

int x;

With the same reasoning, the following is ok:

#include <cstdio>

extern int x;
extern int x;
int x = 42;

int main (){
    printf("%d\n", x);
    return 0;
}

Header and source files

In the header file (.hpp), it’s important to only declare functions and variables without defining it, specially if we are using the source (.cpp) file. Otherwise we may run into multiple definition errors. Consider the following example:

//some_header.hpp
int x;
//some_source.cpp
int local_function(){
    x=2;
}
//main.cpp
#include "some_header.hpp"
int main(){
    return 0;
}

We may compile them like:
g++ -E main.cpp some_source.cpp

After macro expansions and linking, it’s the same we were compiling a sigle source file like this:

//from some_source.cpp
int x; // #include "some_header.cpp" expanded
int local_function(){
    x = 2;
}
//from main.cpp
int x; // #include "some_header.cpp" expanded
int main(){
    return 0;
}

And here we get x multiply defined. Note that include guards wouldn’t solve the problem, since main.cpp and some_source.cpp were expanded and compiled independently.

Further reading

http://publications.gbdirect.co.uk/c_book/chapter4/linkage.html
http://en.wikipedia.org/wiki/Include_guard

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s