"I don't know the key to success, but the key to failure is trying to please everybody."
- Bill Cosby
More pages: 1 ... 11 ... 21 ... 31 ... 41 ... 51 ... 61 ... 71 ... 81 ... 91 ... 101 ... 111 ... 121 ... 131 132 133 134 135 136 137 138 139 140 141 ... 151 ... 161 ... 171 ... 181 ... 191 ... 201 ... 211 ... 221 ... 231 ... 241 ... 251 ... 261 ... 271 ... 281 ... 291 ... 301 ... 311 ... 321 ... 331 ... 341 ... 351 ... 361 ... 371 ... 381 ... 391 ... 401 ... 411 ... 421 ... 431 ... 438
Query FailedHumus
Friday, June 18, 2010

Yury, yes that's a problem. It will only detect on a 4-byte granularity. If you have a bunch of chars or bools it will only detect if all four are uninitialized. You could potentially make special cases for those though. Like a range of bools where all are initialized to something else than 0 or 1 and check on byte level. For chars it's trickier since no particular value can be considered "invalid". And bitfields are pretty much hopeless.
Anyway, even if it doesn't catch everything, it catches many. And I suppose once an ASSERT() triggers you better look over all variables in the class.

sqrt[-1]
Friday, June 18, 2010

Lots of suggested ways of finding initialised member variables here:
http://stackoverflow.com/questions/2099692/easy-way-find-uninitialized-member-variables

from compiler flags in gcc (and VC team systems) to external tools.

Mike
Friday, June 18, 2010

Is there any reason why you are not handling the initialisation of memory to a known marker value in the memory allocator?
It seems to me this would be consistant with c++ ways of working (no risk of overwriting vtable ptrs etc ) and not require class_init macro. Of course I probably have only part of the picture, maybe use of inplace new for example ...
Mike

Arseny Kapoulkine
Friday, June 18, 2010

There is one thing about class layouts that drives me crazy. And this is changing your memory layout between builds. This leads to all sorts of weird "unreproducible" bugs.

Some compilers (gcc) allow you to declare a zero-size array member, though that's not portable.

Anyway, why do you need those markers? If that's a debugging feature, just work on the whole class.

fmoreira
Friday, June 18, 2010

@Yuri: I think it was just a way for Humus to exemplify what he means. You could define a 1byte code to initialize all the data.

The main problem here is that actually 0xBAADC0DE ( or every else code ) can be valid data for some variables, so you could get false positives.
But don't get me wrong, this approach is very cleaver!

What about static code analyzers? Shouldn't these kind of tools check for this type of flaws?

Yury
Friday, June 18, 2010

Does it really works? Consider the following example:

CLASS_BEGIN();
u8 byte0;
u8 byte1;
u8 byte2;
u8 byte3;
CLASS_END();

MyClass::MyClass()
: byte0(0)
, byte1(0)
// oops, missed one
, byte3(0)
{
CLASS_VERIFY();
}

Verification function will do a lookup for 0xBAADCODE, but won't find since three of four bytes were changed. In the same time one variable wasn't initialized at all.

Yes, byte2 will have deterministic value, though it will vary from build to build as class description changes.

Will F
Friday, June 18, 2010

Ugh, never mind; I fail at reading comprehension

Will F
Friday, June 18, 2010

Neat technique, but one question: what do CLASS_BEGIN() and CLASS_END() expand to? I'm not clear how you'd convert those macros to a range of variables to initialize without adding new members to the class (which seems like an undesirable side effect)

More pages: 1 ... 11 ... 21 ... 31 ... 41 ... 51 ... 61 ... 71 ... 81 ... 91 ... 101 ... 111 ... 121 ... 131 132 133 134 135 136 137 138 139 140 141 ... 151 ... 161 ... 171 ... 181 ... 191 ... 201 ... 211 ... 221 ... 231 ... 241 ... 251 ... 261 ... 271 ... 281 ... 291 ... 301 ... 311 ... 321 ... 331 ... 341 ... 351 ... 361 ... 371 ... 381 ... 391 ... 401 ... 411 ... 421 ... 431 ... 438