According to this question, Visual C++ 2005 (and also 2008/2010) does not zero initialize correctly data members.
Since I have a code which requires the standard behaviour, and which crashes in release mode (and not in debug), I suspect the issue comes from here.
Now, the problem is that the code base is quite large, and manually inspecting classes i开发者_如何学JAVAs difficult.
Is there a compiler option to trigger a warning on this non standard behaviour of MSVC ? With /W4, you get the warnings about some non standard extensions (conversions from rvalues to references, missing typename
keyword), but not for this particular problem.
EDIT: I suspect code like that to cause trouble (pasted from the linked question)
include <cassert>
struct B { ~B(); Foo* m; };
int main()
{
B * b= new B();
assert ( b->m ==0);
}
in other portions of the code I have things like
B* b = new B();
and then, later,
if (b->m) { b->m->bar(); }
and b->m
should be zero per the standard, but it's likely not (except in debug mode). I would like to detect such code (like a warning "m
used without being initialized" or something)
Is this about foo::foo () : member () { }
? Paste some example (code) of the problem you are seeing. In standard C++ implementation, the member should have value 0 (assuming it is of a fundamental type). However some older compilers do not do/implement this correctly and just leave it uninitialized. AFAIK there is no warning for this. You will have to go through the code and initialize the member with 0 or other value explicitly.
asper charles comment below, the compiler should be zero init before the ctor is called.
8.5 An object whose initializer is an empty set of parentheses, i.e., (), shall be
value-initialized. ... Value-initialization for such a class object may be implemented
by zero-initializing the object and then calling the default constructor
12.1/7 A non-user-provided default constructor for a class ... performs the set of
initializations of the class that would be performed by a user-written default
constructor for that class with no ctor-initializer (12.6.2) and an empty
compound-statement.
12.6/4 If a given non-static data member or base class is not named by ... in
initialiser list ... the entity is not initialized.
however, remember effective C++, if you declare a dtor then you should also declare a copy ctor, ctor and self-assignment (even if you declare as private)
Don't work around it, attack it directly.
You'll need a C++ parser. Using the parser you'll have to track the types of variables which have no been properly assigned within each constructor of the classes. Once you've got that going it's simply a matter of inserting the proper syntax to make initialization happen in a desirable way. It's not a simple script to write but it'll save you loads of headache later.
FIrst step is just getting output from the parse tree to label problems for you:
class Foo{
public:
Foo(int a) : mA(a){}
private:
int mA, mB;
};
you'll want your script producing messages like: In class Foo :: missing initializer mB
Then get brave and transform that output into an instruction set to traverse the parse tree and insert missing items so that your code looks like:
class Foo{
public:
Foo(int a) : mA(a), mB(0){}
private:
int mA, mB;
};
So my best advice is to not try to work around the issue, attack it directly. If you still have problems after that, grab your nearest static code analyzer and memory analyzer. Those are the tools that will help you best of all.
Are you sure you (the people purportedly citing the ISO C++ Standard) are actually citing it? And not being confused with the text for updated versions specified in TR's which are not actually Standards? Or C++11 which probably will be soon, but one can hardly expect MS to conform to something not yet officially a Standard.
精彩评论