2

There is a code:

 float x=-8.92;
 int y=5;
 printf("%u\n", sizeof x+y);
 printf("%u\n", sizeof (x+y));

Conclusion:

9
4

Why is this happening(result 9)? After all, these are simple unary operations.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • 5
    `sizeof x+y = sizeof(x)+y = 4+5 =9` – Krishna Kanth Yenumula Dec 24 '20 at 13:44
  • 3
    `sizeof x == 4` -> `y == 5` -> `4 + 5 == 9` – Cid Dec 24 '20 at 13:44
  • 1
    `sizeof` does not need brackets. Brackets are necessary only for data type e.g. `sizeof (int)`. – i486 Dec 24 '20 at 13:44
  • 1
    Please see this post [here](https://stackoverflow.com/questions/28075100/when-should-we-use-sizeof-with-and-without-parentheses) about when to use the parentheses. – costaparas Dec 24 '20 at 13:45
  • 1
    @i486 *`sizeof` does not need brackets. Brackets are necessary only for data type e.g. `sizeof (int)`* Which means you should always use them. Nevermind they make bugs like those demonstrated by this program impossible. – Andrew Henle Dec 24 '20 at 14:00
  • regarding; `float x=-8.92;` The literal: `-8.92` is declaring a `double` value which is then being converted to a `float` value. To declare a `float` value use: `-8.92f` Notice the trailing `f` – user3629249 Dec 25 '20 at 03:28
  • regarding: `printf("%u\n", sizeof x+y); printf("%u\n", sizeof (x+y));` The `sizeof` returns a `size_t`, which is a `unsigned long int` A `u` is not a valid output format specifier for a `size_t` Suggest using: `%zu` – user3629249 Dec 25 '20 at 03:31
  • @AndrewHenle Brackets cannot help to someone who is writing `sizeof (x+y)`. – i486 Dec 25 '20 at 10:14
  • @i486 The meaning of `sizeof (x+y)` is clear. What help is needed there? If that's not what the programmer meant, that's not a problem with the language syntax and more than replacing `x + y` with `x / y` would be. – Andrew Henle Dec 25 '20 at 15:48

4 Answers4

4

The sizeof operator has higher precedence than the binary addition operator +. So this:

sizeof x+y

Parses as:

(sizeof x)+y

So in the first expression you're getting the size of a float which is 4 on your system and adding the value 5 to that, resulting in 9. For the second expression, the subexpression x+y has type float because of the usual arithmetic conversions, so the result is 4 which is what's printed.

dbush
  • 205,898
  • 23
  • 218
  • 273
3

This expression

sizeof x+y

is equivalent to the expression

( sizeof x ) + y

So as sizeof x is equal to sizeof( float ) that is 4 then the result of the original expression is equal to 9.

The operator sizeof is an unary operator and its operand is in turn an unary expression. That is the operator in particularly is defined like

sizeof unary-expression

x + y is an additive expression while the variable x as a primary expression is in turn an unary expression. Thus the operator is applied to the variable x.

On the other hand, the expression ( x + y ) is a primary expression and due to the usual arithmetic conversions has the type float. So in this case that is when the expression is written like sizeof( x + Y ) the operator sizeof is again applied to a primary (unary) expression and is equivalent to sizeof( float ).

Pay attention to that instead of the conversion specifier %u you shall use the conversion specifier %zu in the calls of printf. The type of the both expressions sizeof x + y and sizeof( x + y ) is size_t that is an implementation defined type that usually is an alias for the type unsigned long. For the type size_t there is defined the conversion specifier zu that you shall use. Otherwise a call of printf with an incorrect conversion specifier can invoke undefined behavior.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
2

sizeof x+y is the same as (sizeof x) + y, i.e. sizeof has higher precedence than +.

Your compiler should have warned you about the mismatch between the printf() format string (%u) and the argument (size_t, int or other) - if you're using GCC, you should add -Wall -Wextra to your compilation command.

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
  • I will definitely study "- Wall -Wextra". Thanks for the tip . – The person with the question Dec 24 '20 at 13:57
  • 1
    The actual type of the argument is size_t in both calls, the correct format specifier is `%zu`. – zwol Dec 24 '20 at 13:58
  • @zwol, `int` + `size_t` is not necessarily `size_t`. But yes, I did get `x` and `y` the wrong way around - now fixed. – Toby Speight Dec 24 '20 at 14:00
  • 1
    @TobySpeight I guess technically you _could_ have `size_t` be smaller than `int` (minimum maximum for `size_t` is 65536, same as both `unsigned short` and `unsigned int`) but that seems like a really weird ABI to me. Do you know of a real ABI that does that? – zwol Dec 24 '20 at 15:55
  • Oh yes, it does sound very unlikely, I'll grant that. No, I don't know of such systems (but I tend to work with mainstream Unix workstations, so I'm not likely to). Also, I struggle to memorise the common type of signed and unsigned values for arithmetic. Anyway, thanks for pointing out that I'd forgotten which variable was a `float`. – Toby Speight Dec 24 '20 at 15:57
0

The result of “sizeof” depends on the location of the brackets. Why?

Because "brackets" override operator precedences.

alk
  • 69,737
  • 10
  • 105
  • 255