Find Source of random behavior in C++ code
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

I'm having a really hard time figuring this out.

https://github.com/buhrmi/stellar-core/blob/master/src/ledger/AccountFrame.cpp#L376

Even though the variable isnew is a boolean and only ever set to true/false or 1/0 in the code, it sometimes has funny values like "46" or "894334" ... Can you guys help me figure out what's wrong here?

awarded to db3000
Tags
c++
debug

Crowdsource coding tasks.

5 Solutions


A bool representation in memory is always at least a byte, you can have details here.
http://stackoverflow.com/questions/19351483/how-is-a-bool-represented-in-memory

When you test a true value, it is better to test just

if (isnew)

than

if (isnew==1)
I changed the code but I still get some weird behaviour
buhrmi over 6 years ago

in c++ you are guaranteed that 0 means false, and every other non-zero value means true, so in your case is plausible that true get represented by strange bit patterns.

if you want to have a more sensible output, you can use the std::boolalpha to print a boolean as true or false:

std::cout << std::boolalpha 
          << "boolalpha true: " << true << '\n'
          << "boolalpha false: " << false << '\n';

will print

boolalpha true: true
boolalpha false: false 
Winning solution

You have some constructors for AccountFrame that don't initialize isnew, for example:

AccountFrame::AccountFrame(LedgerEntry const& from)
    : EntryFrame(from), mAccountEntry(mEntry.data.account())
{
    mUpdateSigners = !mAccountEntry.signers.empty();
}

Is it possible that you are initializing an object using this constructor and then calling storeUpdate(), in which case isnew has an unspecified value, probably whatever was randomly in the stack/heap at that position. Can you making sure isnew is explicitly initialized in all constructors?

As to the other points, there is no guarantee of what the internal representation of true or false is, and some random values in memory may map to neither of them. However, you are guaranteed that true will convert to 1 when cast to an integer, and that a bool will be promoted to an integer automatically, so the following is safe (assuming isnew is initialized to true or false):

if (isnew == 1) {
    // ...
}

references

You seem to be using C++11, here's the reference from the spec:

8.5 Initializers [dcl.init]

...

6 To default-initialize an object of type T means:

— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is an array type, each element is default-initialized;

— otherwise, no initialization is performed.

11 If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value.

So bool is not a class type or an array type, and thus it has no initialization performed on it by default and has an "indeterminate" or random value, Also interesting is that this random value may be considered as neither true nor false:

3.9.1 Fundamental types

...

Footnote 47) Using a bool value in ways described by this International Standard as “undefined,” such as by examining the value of an
uninitialized automatic object, might cause it to behave as if it is neither true nor false.

Finally, about converting bool to integer:

4.7 Integral conversions

...

7 If the source type is bool, the value false is converted to zero and the value true is converted to one.

C++11 spec can be found here: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf


Sorry to disagree, but I don't think the "funny values" coming from isnew or the only reason you would see a non 0 or 1 in a bool is if the variable was uninitialized and you haven't assigned it a value in the code.

Change line 28 in AccountFrame.h to =true or =false and see if the problem goes away.


Hi buhrmi,

it seems you awarded the bounty to the wrong person or changed your mind.
http://www.cplusplus.com/forum/beginner/172636/

Thanks,

Sam

View Timeline