Strange value

A

Anon Email

Hi people,

I'm playing around with Bartosz Milewski's code at the moment, and I
got the following strange results upon execution of the code included
further below. Please be aware that I deliberately tweaked the code to
produce these results:

Matter for 0 created
Hello from world 1.
Matter for 2009196833 created
Hello from world 2.
Good bye from world 2.
Matter in 2009196833 annihilated
Good bye from world 1.
Matter in 0 annihilated

The code is:

#include <iostream>

class Matter
{
public:
Matter (int i)
: _identifier (i)
{
std::cout << " Matter for " << _identifier << " created\n";
}

~Matter ()
{
std::cout << " Matter in " << _identifier << " annihilated\n";
}
private:
const int _identifier;
};

class World
{
public:
World (int i)
: _identifier (i), _matter (_identifier) // initializing
embeddings
{
std::cout << "Hello from world " << _identifier << ".\n";
}

~World ()
{
std::cout << "Good bye from world " << _identifier << ".\n";
}
private:
const Matter _matter; // Embedded object of type Matter
const int _identifier;
};

World TheUnivers (1);

int main ()
{
World myWorld (2);
}

Now, I know that "int" should be declared before "Matter" in class
"World". I deliberately changed the order to check out the results.
What on earth is 2009196833? Shouldn't this value be zero, as there is
no preceding initialization for the "Matter" object within the
"myWorld" object? i.e., the "Matter" for both "World" objects should
be equal to zero...?

Strange.

Deets
 
I

Ivan Vecerina

Anon Email said:
Hi people,

I'm playing around with Bartosz Milewski's code at the moment, and I
got the following strange results upon execution of the code included
further below. Please be aware that I deliberately tweaked the code to
produce these results:
....
class World
{
public:
World (int i)
: _identifier (i), _matter (_identifier) // initializing
.....
const Matter _matter; // Embedded object of type Matter
const int _identifier;
};

Note that the compiler always initializes data members in the
order of their declaration. For instance, _matter before _identifier.
As a consequence: _matter (_identifier)
leads to undefined behavior: it initializes _matter with
a variable that hasn't been initialized yet.

....
Now, I know that "int" should be declared before "Matter" in class
"World". I deliberately changed the order to check out the results.
What on earth is 2009196833? Shouldn't this value be zero, as there is
no preceding initialization for the "Matter" object within the
"myWorld" object? i.e., the "Matter" for both "World" objects should
be equal to zero...?

Welcome to "Undefined Behavior" (a.k.a. UB). To allow optimal
performance, the C++ language definition says things like
"if no value has been assigned to a variable, it can have any value,
and it is even illegal to try to read that value". If your code
triggers UB, anything may happen at run-time, there is no safety net.

In C++, you must know what you are doing.

This said, several compilers or code verification tools can flag
the error above, and emit a warning during compilation.


hth -Ivan
 
M

Mike Wahler

Anon Email said:
Now, I know that "int" should be declared before "Matter" in class
"World". I deliberately changed the order to check out the results.
What on earth is 2009196833? Shouldn't this value be zero, as there is
no preceding initialization for the "Matter" object within the
"myWorld" object? i.e., the "Matter" for both "World" objects should
be equal to zero...?

Uninitialized != zero. If you want an object's initial
value to be zero(*), you must specifically initialize it
with that value (except for statically defined objects).

-Mike
* for object types where 'zero' has meaning.
 
A

Anon Email

Thanks guys.

When I tweaked the code I was aware that I was passing Matter (int i)
uninitialized arguments. I did this on purpose to see what would
happen. I'm curious to know where the output values come from. The
first object that gets created receives an assumed value of zero, so I
would have thought that the second object would also get zero. (Is
there some sort of default initializing taking place?) Instead it gets
that massive value (2009196833), which looks like it might be the
value limit of an integer, or something. The third one is 2147348480,
the fourth is 8 and the fifth is 2009246515.

These values look pretty random. But I'm not convinced. Regardless of
when I compile them or how often I compile them, the values are the
same. There must be more to it...and this is what I hope to find out.

Cheers, and thanks again.

Deets
 
M

Mike Wahler

Anon Email said:
Thanks guys.

When I tweaked the code I was aware that I was passing Matter (int i)
uninitialized arguments. I did this on purpose to see what would
happen. I'm curious to know where the output values come from.

Anywhere. Everywhere. Nowhere. Your nasal passages. Or somewhere
else. The language definition specifically denotes the result
of such situations as *undefined*, thus there is no predictable
behavior.
The
first object that gets created receives an assumed value of zero,

Assumed by you. But this is an incorrect assumption.
so I
would have thought that the second object would also get zero.

so any deductions following from your incorrect assumption are
suspect.
(Is
there some sort of default initializing taking place?)

No.

Instead it gets
that massive

make that 'random'.
value (2009196833), which looks like it might be the
value limit of an integer,

Or it could be your shoe size, the age of the universe, or
some other value. The behavior is *undefined*.
or something. The third one is 2147348480,
the fourth is 8 and the fifth is 2009246515.

Three more random values, which are the result of *undefined*
behavior.
These values look pretty random.

They are. The code which produced them is specifically identified
by the language to have *undefined* behavior.
But I'm not convinced.

Up to you. :)
Regardless of
when I compile them or how often I compile them, the values are the
same.

If you're using a multitasking OS (e.g. Windows) try compiling/
running it again with additional tasks already running, try it
on a different machine with the same compiler, etc.
But your results, whatever they might be, still cannot be used
to identify a specific, predictable behavior, from the language
perspective.

There must be more to it...and this is what I hope to find out.

There indeed can be much more to it (undefined behavior). The
possible manifestations of UB are theoretically limitless.
So I suppose you'll keep busy for a while. :)

-Mike
 
D

Dave O'Hearn

These values look pretty random. But I'm not convinced. Regardless of
when I compile them or how often I compile them, the values are the
same. There must be more to it...and this is what I hope to find out.

Leftover stuff from static initialization routines getting called
before main() starts, or from deallocated objects that had their
memory returned to the heap... stuff like that. It is not quite
"random", but it is undefined. If you compile with different flags, on
another platform, on a different version of your compiler, etc., you
may (or may not) get completely different values.
 
A

Anon Email

Thanks guys.

Interesting. I always find the concept of "randomness" or "undefined
behaviour" interesting when it comes to computers.

Cheers,

Deets
 
A

Anon Email

Thanks guys.

I love finding out what goes on behind the scenes.

Cheers,

Deets
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,148
Messages
2,570,838
Members
47,385
Latest member
Joneswilliam01

Latest Threads

Top