开发者

Global const initializing and difference between constructor in .h or .cpp file

开发者 https://www.devze.com 2023-01-30 05:35 出处:网络
I was wondering why sometimes my global const defined in seperate .h file isn\'t properly initialized when I need it. Some tests lead me to situation that I can\'t understand. I don\'t know how to exp

I was wondering why sometimes my global const defined in seperate .h file isn't properly initialized when I need it. Some tests lead me to situation that I can't understand. I don't know how to explain it, so here's the code:

main.cpp

#include <iostream>
#include "class.h"
using namespace std;

A a;
B b;

int main(int argc, char* argv[]){
A aa;
B bb;
cout<<a.a<<" "<<aa.a<<endl;
cout<<b.b<<" "<<bb.b<<endl;
return 0;
}

class.h

#ifndef CLASS_H
#define CLASS_H
#include "const.h"

class A {
public:
A();
float a;
};

class B {
public:
B():b(CONST){}
float b;
};
#endif

class.cpp

#include "class.h"
A::A()
: a(CONST){}

const.h

#ifndef CONST_H
#define CONST_H
#include <limits>
using namespace std;

const float CONST = numeric_limits<float>::has_infinity ? 
        -numeric_limits<float>::infinity() : 
        -numeric_limits<float>::max();
#endif

After running above code I get:

0 -1.#INF

-1.#INF -1.#INF

when actually I would like to get 4 times '-1.#INF'. Why does it happen this way? If CONST would be '1' instead of above formula, it would work perfectly.

I can "fix" it by making static getConst() method:

static float getConst(){
static const float CONST = numeric_limits<float>::has_infinity ? 
        -numeric_limits<float>::infinity() : 
        -numeric_limits<float>::max();
return CONST;}

b开发者_运维百科ut it just doesn't "feel" right. On other hand I just need two of those above... But maybe there's some other way?

And, most importantly, why class B gets "right" CONST and class A don't?


The order of initialization of global object in different translation unit is not guarantee.

Please have a look at this stackoverflow question: Static variables initialisation order


Constant objects have internal linkage, so you get a separate copy of CONST in each compilation unit that includes const.h. In this case, you'll get one in main.cpp, and one in class.cpp. You also have your two global objects in main.cpp.

C++ does not define the order in which global objects in different compilation units are initialised. As constructor is called from main.cpp, and needs the global constant from class.cpp, which may not yet be initialised. In your particular case, it hasn't been, so you get the incorrect value you saw. Bs constructor is inline, so it uses the global constant from main.cpp, which has been initialised since it is defined earlier in the same compilation unit.

By making the constant a function-static object, it is now guaranteed to be initialised when that function is first called.


I don't see the contents of const.h anywhere so I can only guess what CONST is (a macro?).

That aside, in your code example, the member variable A::a is not initialized. Hence, it could have any value - it's uninitialized.


If I'm understanding your question properly then I believe the problem is because the order of initialisation of any global objects is not defined.

0

精彩评论

暂无评论...
验证码 换一张
取 消