9
char  a, b;     
printf("%d", sizeof(a+b));

What will printf write to the screen?

I thought because sizeof(char)=1, that sizeof(a+b) will be also 1, but it turned out to be 4. I don't understand this, why does it write 4 if we are adding two chars?

Nebeski
  • 610
  • 4
  • 14

2 Answers2

12

In C language operands of almost all arithmetic operators are subjected to implicit conversions called usual arithmetic conversions or, in this case, integer promotions. Operands of type char are promoted to type int and the actual addition is performed within the domain of int (or unsigned int, depending on the properties of char on that platform). So your a + b is actually interpreted as (int) a + (int) b. The result has type int and sizeof(int) is apparently 4 on your platform. That 4 is what you see.

And don't use %d to printf the result of sizeof. The result of sizeof has type size_t, while %d requires an int argument. So, either use the proper format specifier

printf("%zu\n", sizeof(a+b));

or at least cast the argument if you are sure it fits

printf("%d\n", (int) sizeof(a+b));
AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Never heard of _integral promotions_. – chux - Reinstate Monica Feb 09 '16 at 19:55
  • @chux - it's the old C90 term - the formal standard term is integer promotions. See [here](http://stackoverflow.com/questions/12094412/what-is-the-difference-between-integral-promotion-and-balancing-in-c) and [here](http://stackoverflow.com/questions/10660758/integral-promotion) for more – Krease Feb 09 '16 at 19:56
  • @Chris I see: --> "Integral promotions" is the old C90 term, the formal standard term is integer promotions. – chux - Reinstate Monica Feb 09 '16 at 19:57
  • Thank you, what would sizeof(a+b) return if a and b are float, and sizeof(float)=4? Will it promote/demote it or will it remain in float? – Nebeski Feb 09 '16 at 19:57
  • @Nebeski suggest you try that. – Weather Vane Feb 09 '16 at 19:59
  • It returned 4, so I guess it stays in float. – Nebeski Feb 09 '16 at 20:00
  • 2
    @Nebeski: `float` is not promoted. Back in some ancient pre-standard version of C `float` used to be unconditionally promoted to `double`. But the idea was abandoned before the release of C89/90. In standard C `float` is not promoted to `double` in such expressions. (When passing arguments to functions with undeclared parameters `float` is implicitly converted to `double` though.) – AnT stands with Russia Feb 09 '16 at 20:01
  • @AnT, `float` is promoted to `double` only in case of one `double` appearing as the other operator in an arithmetic operator, and when passing a `float` as a parameter to a function with unspecified parameter type (incomplete or vararg). I haven't heard about this to be abandoned somewhat. At least, I'm programming with that assumption in mind without having warned of it to have changed. – Luis Colorado Feb 11 '16 at 07:12
  • @Luis Colorado: See "C Reference Manual" by Dennis Ritchie - one of the first C language "specs". It explicitly says *"6.2 Float and double. All floating arithmetic in C is carried out in double precision; whenever a float appears in an expression it is lengthened to double by zero padding its fraction"*. (https://www.bell-labs.com/usr/dmr/www/cman.pdf) Moreover, if I'm not mistaken, the first edition of K&R C also included this rule. – AnT stands with Russia Feb 11 '16 at 09:21
  • Also, see the reference to "C Primer" in this question http://stackoverflow.com/q/13425012/187690, which implies that unconditional promotion of `float` to `double` was indeed present in K&R. – AnT stands with Russia Feb 11 '16 at 09:31
  • @AnT, yes... that's right, but that has been dropped a lot of time ago, as many architectures can work without promoting all `float`s to `double`s. I think my observation was dated from ANSI spec onwards, as it deals with parameters not specifically declared as `float` (the case of varargs and unspecified parameter prototypes of the form `type func();`. Allow me some possible margin of mistake, as I don't have K&R in front of me and I speak from my (poor) memory. – Luis Colorado Feb 11 '16 at 12:27
6

This is not the same as sizeof(char), the argument (i.e. the result of the addition) is promoted to int so sizeof(a + b) is in fact equivalent to sizeof(int). If you cast the result to char it will be what you expect. Also, the correct format specifier for sizeof result which is size_t is %zu and not %d.

Try

printf("%zu", sizeof((char) (a + b)));
Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97