Re: VC++2008: STL access violation depending on runtime library being used -- bug or undefined behavior?
"Alan Carre" <alan@twilightgames.com> wrote in message
news:etG9sej4IHA.2348@TK2MSFTNGP06.phx.gbl
"Igor Tandetnik" <itandetnik@mvps.org> wrote in message
news:Ot%238JLj4IHA.4352@TK2MSFTNGP05.phx.gbl...
I don't see any global objects in the OP's code referencing any other
global objects. There's one global object, G_Test, and two local
variables.
Sure, errno. There's a global in the OP but you can't actually see
it. It's not written in the post, but it's a global variable that's
"in the program".
I have no idea what this is supposed to mean. Variables that exist but
you can't see them? Are they in any way related to fairies?
Others include the zillion globals used by the STL some of which will
be supporting variables for things such as std::stringstream.
If STL implementation uses global variables internally, it's the
implementation's job to maintain them in a way that doesn't interfere
with valid programs. If it fails to do so, it's buggy. Which seems to be
the case here.
Consider for example the specification of cin, cout et al - global
objects that are mandated by the standard:
27.3/2 The objects are constructed, and the associations are established
at some time prior to or during first time an object of class
basic_ios<charT,traits>::Init is constructed, and in any case before the
body of main begins execution.264) The objects are not destroyed during
program execution.265)
Footnote 265: Constructors and destructors for static objects can access
these objects to read input from stdin or write output to stdout or
stderr.
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#369
If a translation unit includes <iostream>, or explicitly constructs an
ios_base::Init object, these stream objects shall be constructed before
dynamic initialization of non-local objects defined later in that
translation unit.
I know this to be true because I use the STL extensively and if I
declare a global STL object and attempt to reference it in a global
that gets constructed before the STL global does, then I get a crash.
Here you are talking about two global objects you yourself declare - not
some invisible objects allegedly introduced by the implementation. Yes,
the order of construction and destruction of global objects is (almost
always) undefined. It is in fact irrelevant that one or more of those
objects happen to be of a type defined by STL: the exact same problem
would occur for two global objects of user-defined types.
But again - the program we are discussing declares exactly one global
object. Everything you say is true, but it has no bearing on the problem
at hand.
Could you point to the rule in the C++ standard this code violates? I
can't think of any.
This code does not violate any rule in the C++ standard. Nor does
this:
char* c = 0;
*c = 0;
Does too.
5.17/1 There are several assignment operators, all of which group
right-to-left. All require a modifiable lvalue as their left operand...
3.10/14 If an expression can be used to modify the object to which it
refers, the expression is called modifiable. A program that attempts to
modify an object through a nonmodifiable lvalue or rvalue expression is
ill-formed.
An expression *c where c is a null pointer doesn't refer to any object,
and thus is not a modifiable lvalue, and hence cannot appear on the left
hand side of an assignment operator.
See also
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not
necessarily a good idea. It is hard to be sure where they are going to
land, and it could be dangerous sitting under them as they fly
overhead. -- RFC 1925