gEdringer
gEdringer

Reputation: 16583

Sizeof and expressions?

So I just read a chapter about sizeof() in my C++ book. What I read is that you only need the parenthesis after sizeof if the operand is a type, where's you can skip the parenthesis when you have an expression, so what I did was did my own test to see what's going on with this. I used the the following code to see what I will get:

int main(){

    cout << sizeof 5 + 5<< endl;
    cout << sizeof 10 - 5<< endl;
    cout << sizeof 5 * 5<< endl;
    cout << sizeof 4.5 + 5.5<< endl;
    cout << sizeof 10.5 - 5.5<< endl;
    cout << sizeof 2.5 * 5<< endl;
    cout << sizeof 10.0 / 5.0<< endl;
    cout << endl;

    cout << sizeof 5 << endl;
    cout << sizeof 5.0 + 5.0 << endl;
    cout << sizeof 5.5 << endl; 

    return 0;
}

The output I get is this:

9
4294967295
20
13.5
2.5
40
1.6
4
13
8

How does that work? When I have two integer types, bot 4 bytes, when doing an addition, how it becomes 9 bytes? Is it due to one byte for the + operator? But still, if so, then how did the 10-5 came out as 4294?

Upvotes: 0

Views: 249

Answers (2)

Antoine
Antoine

Reputation: 14064

sizeof 5 + 5 it's parsed as (sizeof(5)) + 5 and not sizeof(5+5) due to operators priorities, so it becomes 4 + 5 and 9. For more info about this, like chris said, have a look at this table.

For the substraction it's the same, but as the type of the expression is size_t which is unsigned, the substraction is done on unsigned ints which wrap around 2^32 which is 4,294,967,296. Thererfore, sizeof 10 - 5 is 4 - 5 which becomes (4,294,967,296) - 1 in 32 bit unsigned arithmetic, that's the 4,294,967,295 you're getting.

Going further

Internally during the parsing step of the compilation process, each source code statement is transformed into an expression tree (often called AST), you can look here for exemple if you're curious about these things.

For a more hands-on practical understanding, install the clang compiler and play with

clang -Xclang -ast-dump -fsyntax-only source.cpp

Which displays the tree from your code. Really nice, but I recommand short code because the output can be overwhelming otherwise ;)

Upvotes: 16

Mark Jerde
Mark Jerde

Reputation: 324

sizeof is only binding to the first thing that follows it.

An integer literal is four bytes, while a floating point literal is eight bytes. You then follow each of those two values with an addition, subtraction multiplication or division and get the expected mathematical result. e.g. sizeof(5) -> 4, 4 + 5 -> 9.

The second value in your example is large because of underflow (4294967295 == 0xFFFFFFFF == 4-5 in unsigned use).

Good luck!

Upvotes: 3

Related Questions