Re: Global initialisation fault
chris.dearlove@gmail.com wrote:
kanze wrote:
There's no requirement vis-a-vis printf,
Are you saying that a valid order is, if the rules didn't
apply to main (or if somehow we could get this code in place
apart from that)
(a) Evaluate wibble, as 0
(b) Initialise john, hence setting wibble to 6
(c) Call printf, passing 0?
No. I'm saying that in the general case, there is no guarantee
that john has been initialized before printf is called. If the
printf was in the constructor of a static object in another
file, for example, and used wibble, the standard doesn't say
whether john will have been initialized or not.
If you're not using that compiler, why worry about it?
Because someone who has some of my code does. And whilst the
code obviously hasn't been tested by me on that compiler, if
it doesn't work, I like to know why. And if this fails, it's
not surprising the more subtle case I have fails too.
I know it may be a problem, but frankly, if you cannot test with
the actual compiler in question, you cannot maintain a code base
for that compiler. It just isn't possible. And if people are
using your code, and expecting it to work, with a compiler to
which you don't have access, you have a political problem, not a
C++ problem.
And yes, someone may be making some optimistic assumptions
about code on new compilers, but it's not me.
I'm not sure what EVC++4 is; the current VC++ for Windows
handles the case correctly. If the E in the compiler name
stands for embedded, however, I would suspect an
optimization problem.
Embedded VC++ for WinCE. That is the latest version of that
(I'm told).
probably, the compiler sees that john never gets used,
and eliminates it from the program.
Now that's a thought. The actual code is seriously different
from that shown (anonymous namespace, not global for a start)
but it still has that characteristic. Thanks.
Try taking the address of the variable somewhere in code that is
used. That usually does the trick.
According to the standard, inclusion of a translation unit in a
program is an all or nothing thing; if anything in the
translation unit is present, then the entire translation unit is
present. In many cases, however, it is possible to eliminate
parts of it, under the as if rule; VC++ has an option, for
example, which tells the compiler/linker to use individual
functions as the granularity. Which is fine, as there is no way
a conforming program can tell if an individual function is not
present if it isn't used. Static variables are similar: if they
are not used, AND if their initialization is static or has no
effect on the observable behavior of the program (no side
effects), they can also be eliminated. In your case, that last
condition is not met, so the static variable cannot be
eliminated. But it isn't hard to imagine a compiler missing
this. Especially for embedded systems, where space optimization
is an important feature. (VC++ under Windows gets this right,
even when I request functional granularity. I don't know
whether it is because they actually detect that the variable has
dynamic initialization, or simply that they didn't find the
space optimization worth the bother under Windows.)
--
James Kanze GABI Software
Conseils en informatique orient?e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S?mard, 78210 St.-Cyr-l'?cole, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]