global variable vs static member initialization order

N

n.torrey.pines

Are global variables (and const's) guaranteed to be initialized before
static class members (and methods) ?


const int x = 19907;
int get_x() { return x; }

// another compilation unit:

int get_x();
static int my_class::y = get_x();
 
N

n.torrey.pines

Are global variables (and const's) guaranteed to be initialized before
static class members (and methods) ?

corrected code example:

const int x = 19907;
int get_x() { return x; }

// another compilation unit:

int get_x();
struct my_class { static int y; };
int my_class::y = get_x();
 
A

Alf P. Steinbach

* (e-mail address removed):
Are global variables (and const's) guaranteed to be initialized before
static class members (and methods) ?

No, C++ does not make that distinction. Furthermore, "methods" (ITYM
member functions) require no initialization and are not initialized.
However, there is a distinction for initialization with POD type
constant expression.


const int x = 19907;
int get_x() { return x; }

// another compilation unit:

int get_x();
static int my_class::y = get_x();

See the FAQ item titled "What's the "static initialization order
fiasco"?", and the following items.
 
N

n.torrey.pines

* (e-mail address removed):


No, C++ does not make that distinction.

Between [const] global variables and [const] static members?

So is the behavior of the above code undefined?

Does it make a difference if
a. everything (x, y, get_x's return type) is const ?
b. x is int / other POD, such as a const array of plain structs?

See the FAQ item titled "What's the "static initialization order
fiasco"?", and the following items.

Thanks - I'd seen it, and just looked at it again. What the FAQ
suggests is not completely satisfactory because "construct on first
use" is not thread-safe. I think that moving the relevant
interdepedent code to a single compilation unit would be better (but
not ideal).
 
V

Victor Bazarov

Alf said:
* (e-mail address removed):

No, C++ does not make that distinction. Furthermore, "methods" (ITYM
member functions) require no initialization and are not initialized.
However, there is a distinction for initialization with POD type
constant expression.




See the FAQ item titled "What's the "static initialization order
fiasco"?", and the following items.

I do not believe any of this is relevant here. 'x' is a compile-time
constant. There is no initialisation, it's replaced with its value
in the body of 'get_x' function.

V
 
A

Alf P. Steinbach

* Victor Bazarov:
I do not believe any of this is relevant here. 'x' is a compile-time
constant. There is no initialisation, it's replaced with its value
in the body of 'get_x' function.

I'm not so sure of that. 'x' can serve as constant expression, yes.
The above code necessarily using 'x' as a compile time constant, well, I
don't see that anywhere in the holy standard (do you have a quote?).
 
V

Victor Bazarov

Alf said:
* Victor Bazarov:

I'm not so sure of that.

I wonder what makes you unsure. Have you *ever* seen anything to
suggest that the compiler does *not* replace accessing the variable
with a simple [immediate] value?
'x' can serve as constant expression, yes.
The above code necessarily using 'x' as a compile time constant,
well, I don't see that anywhere in the holy standard (do you have a
quote?).

No, I don't have a quote. My point is that "static initialisation
order fiasco" is applicable here with a *significantly* lower
probability than the use of the constant by replacing with its value.

V
 
A

Alf P. Steinbach

* Victor Bazarov:
I wonder what makes you unsure.

Just what I wrote -- I cannot find any guarantee in the standard.

Have you *ever* seen anything to
suggest that the compiler does *not* replace accessing the variable
with a simple [immediate] value?

No, and I agree that with a quality implementation it's not a practical
problem.

No, I don't have a quote. My point is that "static initialisation
order fiasco" is applicable here with a *significantly* lower
probability than the use of the constant by replacing with its value.

On that I think we can agree. However, until some guarantee is found in
the standard (if it exists), I think it's prudent to code as if there's
no such guarantee. I'd just provide that constant in a header file
(thus having its possible initialization in the compilation unit where
it's used), or perhaps used an enum, or, except for the naming scheme,

int get_x() { static int const x = 19907; return x; }
 
V

Victor Bazarov

Alf said:
* Victor Bazarov:
[..] My point is that "static initialisation
order fiasco" is applicable here with a *significantly* lower
probability than the use of the constant by replacing with its value.

On that I think we can agree. However, until some guarantee is found
in the standard (if it exists), I think it's prudent to code as if
there's no such guarantee. I'd just provide that constant in a
header file (thus having its possible initialization in the
compilation unit where it's used), or perhaps used an enum, or,
except for the naming scheme,
int get_x() { static int const x = 19907; return x; }

For that, why bother with 'x' at all? I understand that there can be
scientific curiosity, but wouldn't it be better to place 'get_x' in
the header and declare/define it like

inline int get_x() { return 19907; }

? Just a thought...

V
 
A

Alf P. Steinbach

* Victor Bazarov:
Alf said:
* Victor Bazarov:
[..] My point is that "static initialisation
order fiasco" is applicable here with a *significantly* lower
probability than the use of the constant by replacing with its value.
On that I think we can agree. However, until some guarantee is found
in the standard (if it exists), I think it's prudent to code as if
there's no such guarantee. I'd just provide that constant in a
header file (thus having its possible initialization in the
compilation unit where it's used), or perhaps used an enum, or,
except for the naming scheme,
int get_x() { static int const x = 19907; return x; }

For that, why bother with 'x' at all? I understand that there can be
scientific curiosity, but wouldn't it be better to place 'get_x' in
the header and declare/define it like

inline int get_x() { return 19907; }

? Just a thought...

As I wrote, and you quoted here, if it was my code, I'd just provide
that /constant/ in the header, no 'get_x'... ;-)
 
V

Victor Bazarov

Alf said:
* Victor Bazarov:
Alf said:
* Victor Bazarov:
[..] My point is that "static initialisation
order fiasco" is applicable here with a *significantly* lower
probability than the use of the constant by replacing with its
value.
On that I think we can agree. However, until some guarantee is
found in the standard (if it exists), I think it's prudent to code
as if there's no such guarantee. I'd just provide that constant in
a header file (thus having its possible initialization in the
compilation unit where it's used), or perhaps used an enum, or,
except for the naming scheme,
int get_x() { static int const x = 19907; return x; }

For that, why bother with 'x' at all? I understand that there can be
scientific curiosity, but wouldn't it be better to place 'get_x' in
the header and declare/define it like

inline int get_x() { return 19907; }

? Just a thought...

As I wrote, and you quoted here, if it was my code, I'd just provide
that /constant/ in the header, no 'get_x'... ;-)

Interface (a function) can be a requirement. Template code often
requires functors, libraries require callbacks...

V
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top