17

Till now I was believing that there is no use of unary + operator.

But then I came across with following example:

char ch;
short sh;
int i;

printf("%d %d %d",sizeof(ch),sizeof(sh),sizeof(i)); // output: 1 2 4

printf("%d %d %d",sizeof(+ch),sizeof(+sh),sizeof(i)); // output: 4 4 4

Does it mean + is doing type conversion here?

Because it is behaving same as following

printf("%d %d %d",sizeof((int)ch),sizeof((int)sh),sizeof(i)); // output: 4 4 4

This forces me to think + is doing type conversion.

But then I try it on double

double f;
printf("%d %d %d", sizeof(+f), sizeof((int)f), sizeof(f)); // output: 8 4 8

This forces me to rethink about unary + operator.

So my second question is: does unary + operator has special effect in sizeof operator?

Community
  • 1
  • 1
A.s. Bhullar
  • 2,680
  • 2
  • 26
  • 32
  • What confuses you about `double`? For your first question: Yes, `+` does conversion (IIRC integer promotions, so `float` doesn't get `double`, but integers get (unsigned) `int` or something with higher rank). – mafso Jul 17 '14 at 14:00

4 Answers4

23

Unary + performs integer promotions on its operand, we can see this by going to the draft C99 standard section 6.5.3.3 Unary arithmetic operators which says (emphasis mine going forward):

The result of the unary + operator is the value of its (promoted) operand. The integer promotions are performed on the operand, and the result has the promoted type.

and section 6.3.1 Arithmetic operands says:

If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions.48) All other types are unchanged by the integer promotions.

Note that all other types are unchanged by the integer promotions and thereofore double stays a double. This would also hold for float as well, which would not be promoted to double.

Also note that using %d for the result of sizeof is undefined behavior since the result is size_t. the proper format specifier would be %zu.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • thanks for mentioning %zu format specifier for sizeof,I never listen about it before – A.s. Bhullar Jul 17 '14 at 17:15
  • " using `%d` for the result of `sizeof` is undefined behavior " in the question above it is giving expected results when do we get unexpected behavior ? – Vinay Shukla May 28 '15 at 05:53
  • @yanivx [undefined behavior](http://en.wikipedia.org/wiki/Undefined_behavior) means it is unpredictable, so behaving in a way that seems reasonable is a possible undefined behavior. But we can find plenty of cases such as [this one](http://stackoverflow.com/q/24296571/1708801) where the compiler takes the liberty to do some unexpected things. There is plenty of UB that does what you expect but it may not in the future. – Shafik Yaghmour May 28 '15 at 09:24
4

When smaller types are involved in an expression with larger types (for example, char is smaller than short which mostly is smaller than int which may be smaller than long), the involved types are promoted to the larger tyoes.

So yes, when you use the unary + operator, you get an int, because int is the natural integer type in C.

Regarding the double type, the natural floating point type for C is double, which is why there's no promotion on values or variables that already are of type double.

The sizeof operator have nothing to do with this.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    If you are going to take precautions, `char` is only mostly smaller than `short` too. A processor that handles only one data width (like a DSP) may be programmed in a standard-compliant C compiler where `char`, `short` and `int` all have the same width (which could be 16-bit, 24-bit or 32-bit, for instance). – Pascal Cuoq Jul 17 '14 at 14:05
  • 1
    In the first paragraph you say that the promotion happens “when smaller types are involved … with larger types”, but the operand of the unary `+` has no involvement with other types (larger or otherwise) in that expression. So the second paragraph does not follow from the first, even though it is otherwise correct. – Arkku Jul 17 '14 at 14:13
  • 1
    @EliasVanOotegem This is exactly why `int8_t` is only defined if it exists and why we have `int_least8_t`. If `int8_t` were always defined, then `int_least8_t` would not make sense, as it could only be `int8_t`. http://stackoverflow.com/a/5254321/139746 – Pascal Cuoq Jul 17 '14 at 15:20
  • @PascalCuoq: well, that shut me up :D, good point. Sign that it's time for me to call it a day – Elias Van Ootegem Jul 17 '14 at 15:29
  • @Joachim short is converted to int because int is natural type for integers , similarly if double is natural type for float then does it converted to double? – A.s. Bhullar Jul 17 '14 at 17:11
  • @A.s.Bhullar *float* will not be promoted to *double* I updated my answer. As my answer says the integer promotions won't effect either. – Shafik Yaghmour Jul 17 '14 at 17:27
4

Operator unary + triggers "initial" usual arithmeric conversions, so all integer operands, which type has lower rank than rank of int and unsigned int are promoted to int (or unsigned int if int type does not cover all values of type being promoted on that implementation).

Grzegorz Szpetkowski
  • 36,988
  • 6
  • 90
  • 137
2

It's not sizeof, it's the unary + itself. The operands of unary + undergo "the usual arithmetic conversions". See, e.g., this other answer involving ordinary addition.

Community
  • 1
  • 1
torek
  • 448,244
  • 59
  • 642
  • 775