13
votes

I have some code spread over three files and I would like to use a fourth "gloabls" file to store some physical constants such as the value of pi. This would avoid repetitive definitions of pi = 4*atan(1.0). After poking around, what I've tried is creating a global header file:

/*globals.h*/
extern double g_pi;

and a global cpp file:

/*globals.cpp*/
#include "math.h"
#include "globals.h"
double g_pi = 4*atan(1.0);

Then I include these file in my main files:

/*mainFile.cpp*/
//Include math and other libraries 
#include globals.h"
int main() {
/*
....
*/
double x = 2*g_pi
/*
....
*/
}

This gives me an undefined reference error to g_pi. I'm using a g++ compiler on Ubuntu. Hopefully its a simple fix! Your suggestions are much appreciated. If more details are necessary I'll be happy to supply them.

5
The problem may lie with the way you build the executable, so you should add whatever you use to do that to your question (Makefile, g++ command line...).alexisdm
Can you include the exact command you execute to compile? And the exact error message?JaredC

5 Answers

17
votes

You could simply use M_PI from the include (there are other constants too).

Edit: your setup is correct. I got a working minmal example:

globals.h

extern double g_tst;

globals.cpp

#include "globals.h"
double g_tst = 4.0;

main.cpp

#include "globals.h"
#include <stdio.h>
#include <stdlib.h>

int main()
{
fprintf (stderr, "g_tst  = %lf \n", g_tst);
return 0;
}

The problem is within your buildsystem

See wikipedia

7
votes

I think the problem is that you've got #include gobals.h instead of #include globals.h. This would give you the undefined references because it isn't inserting globals.h. The C++ precompiler doesn't fail when it can't find a header file. Instead you get an undefined reference message at compilation.

2
votes

The order of linking might be the problem. Try to link the global object file as the last one.

1
votes

g_pi musst not be declared extern in one translation unit. You could use a small #define for this

in globals.cpp

#define MY_EXTERN_CPP

in /*globals.h

#ifdef MY_EXTERN_CPP
    #define MY_CONFIGURATION_EXTERN
#else
    #define MY_CONFIGURATION_EXTERN extern
#endif

MY_CONFIGURATION_EXTERN double g_pi;

so g_pi will be extern in all translation units you include it except globals.cpp

0
votes

I had the same problem. I was using CMAKE, the problem was I didn't put my globals.cpp file into CMAKE executable. This problem should be something similar, nothing wrong with the implementation itself.