14
#include<stdio.h>

int main()
{
    printf("%d\n", sizeof(2147483648));
    printf("%d"  , sizeof(2147483647+1)); 
    return 0;
}

Output:

8  
4

I understand that sizeof(2147483648) is 8 bytes as it cannot fit in 4 bytes and is promoted to long long int. But I do not understand what happens in case of sizeof(2147483647+1)

I found a similar question but it does not discuss the second case.

Community
  • 1
  • 1
user2830528
  • 169
  • 5
  • 3
    Why are you doing this in the first place – Ed Heal Jun 21 '15 at 09:32
  • possible duplicate of [Why is "int i = 2147483647 + 1;" OK, but "byte b = 127 + 1;" is not compilable?](http://stackoverflow.com/questions/6889176/why-is-int-i-2147483647-1-ok-but-byte-b-127-1-is-not-compilable) – GSerg Jun 21 '15 at 09:33
  • 10
    `2147483647+1` is an expression that has two `int` operands so the result is an `int` (and has undefined behavior because of the overflow). Similarly, `-2147483648` is an expression where the `2147483648` is a `long int` that then has the unary minus operator applied to it, – Michael Burr Jun 21 '15 at 09:33
  • 1
    Print not only sizes but also the values. – pasaba por aqui Jun 21 '15 at 09:33
  • @GSerg That is for java, this is c. – RedX Jun 21 '15 at 09:34
  • @RedX I searched for a duplicate and didn't notice it was for Java because the underlying reason is the same. – GSerg Jun 21 '15 at 09:37
  • @Gserg Java does not have unsigned types only signed. This might add to the confusion. – RedX Jun 21 '15 at 09:38
  • 1
    And behavior like this is why an implementation might define `INT_MIN` int `limits.h` as `(-2147483647-1)`. – Michael Burr Jun 21 '15 at 09:41
  • 3
    You really should use `%zu` (C99) to print the value of `sizeof` operator (or convert to int): `printf("%zu\n", sizeof 42);` or `printf("%d\n", (int)sizeof 42);` – pmg Jun 21 '15 at 09:42

1 Answers1

19

The rules of integer constant in C is that an decimal integer constant has the first type in which it can be represented to in: int, long, long long.

2147483648

does not fit into an int into your system (as the maximum int in your system is 2147483647) so its type is a long (or a long long depending on your system). So you are computing sizeof (long) (or sizeof (long long) depending on your system).

2147483647

is an int in your system and if you add 1 to an int it is still an int. So you are computing sizeof (int).

Note that sizeof(2147483647+1) invokes undefined behavior in your system as INT_MAX + 1 overflows and signed integer overflows is undefined behavior in C.

Note that while generally 2147483647+1 invokes undefined behavior in your system (INT_MAX + 1 overflows and signed integer overflows is undefined behavior in C), sizeof(2147483647+1) does not invoke undefined behavior as the operand of sizeof in this case is not evaluated.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • 2
    Are you sure there is undefined behavior here, given that the expression appears as an argument to `sizeof` rather than in a context where it would be evaluated? –  Jun 21 '15 at 09:48
  • 3
    I suspect that it will invoke UB. `2147483647+1` will not be evaluated. – haccks Jun 21 '15 at 09:54
  • 1
    Possibly relevant: [Does not evaluating the expression to which sizeof is applied make it legal to dereference a null or invalid pointer inside sizeof in C++?](http://stackoverflow.com/q/28714018/11683). – GSerg Jun 21 '15 at 09:59
  • I think it does not invoke UB for the same reason that `sizeof *ptr` doesn't. The type will be `int` according to integer promotion rules – M.M Jun 21 '15 at 10:28
  • 2
    As a sidenote: `sizeof(1/0)` also produces the same as `sizeof(int)` – Hagen von Eitzen Jun 21 '15 at 12:10