1

can some please explain how float is the output of this program I am unable to understand

#include <stdio.h>
int main()
{
    int x = 1;
    short int i = 2;
    float f = 3;
    if (sizeof((x == 2) ? f : i) == sizeof(float))
        printf("float\n");
    else if (sizeof((x == 2) ? f : i) == sizeof(short int))
        printf("short int\n");
}

3 Answers3

4

Indeed the ternary operator is not returning quite what you think it is, but it is also not quite what @user15790236 thinks either. The ternary operator is an operator, and as such it expects arguments of the same type on either side of the colon. Since you have different types, the integer is promoted to float, and thus the expression is of type float.

SGeorgiades
  • 1,771
  • 1
  • 11
  • 11
  • 1
    Detail: "the integer is promoted to float" --> "the `short` is promoted to `float`" (or more correctly the "the `short` is promoted `int` and then to `float`") – chux - Reinstate Monica Apr 29 '21 at 08:49
  • I suggest you to add also that with ANSI C, the `float` is an IEEE 754 single-precision binary, so **32 bits** and that the `int` type size is implementation dependent (ANSI C requires only that it should be at least 16 bits, anyway most of the actual common implementation set it to 32 bits). – Zilog80 Apr 29 '21 at 08:54
  • 1
    @Zilog80 Anything to back up [ANSI C](https://en.wikipedia.org/wiki/ANSI_C#C89) specifies `float` as IEEE 754 single-precision binary claim? – chux - Reinstate Monica Apr 29 '21 at 08:59
  • @chux-ReinstateMonica Maybe i'm wrong. It seems to me that [ISO/IEC TR 24732:2009](https://www.iso.org/standard/38842.html) has been included in C11 ? – Zilog80 Apr 29 '21 at 09:34
  • @Zilog80 AKAIK, C has never required IEEE floating point compliance other than the optional `__STDC_IEC_559__`. True that at least partial IEEE 754 is ubiquitous. – chux - Reinstate Monica Apr 29 '21 at 09:47
  • 1
    The integer is *converted* to `float`. The C standard uses the word “promotion” for the integer promotions and the default argument promotions. Those are particular types of type conversions that preserve value—they only convert to a more encompassing type that can represent all the values of the original type, hence “promotion.” In contrast, a conversion from integer types to floating-point types can change the value, depending on details of the types. Such conversions are not always promotions to encompassing types. – Eric Postpischil Apr 29 '21 at 10:59
1

The ternary operator is not returning quite what you think it is.

( (x == 2) ? f : i ) actually returns the value of i, which is by value and is then handled as an int, not a short int - thus, 4 bytes in size according to your 64bit compiler. Put another way, the return from the ternary operator is a copy of what is in i, not i itself.

Prove this to yourself by checking the value of:

sizeof(2)

To get what you seem to expect, you could instead say:

( (x==2) ? sizeof(f) : sizeof(i) )

The next question you may want to consider is why does the compiler pick int for the type when a short would do the trick. Have a peek at Implicit type promotion rules

Obsidian
  • 3,719
  • 8
  • 17
  • 30
0

Since C11, to note the type, rather attempt sizeof(type) compares, use _Generic.

#include <stdio.h>

#define type(X) _Generic((X), \
    short: "short", \
    int: "int", \
    float: "float", \
    double: "double", \
    default: "default" \
)

int main(void) {
  int x = 1;
  short int i = 2;
  float f = 3;
  puts(type(x));
  puts(type(i));
  puts(type(f));
  puts(type((x == 2) ? f : i));
}

Output

int
short
float
float

(x == 2) ? f : i is a float as @SGeorgiades well points out, the type of the a?b:c is the same, regardless if a is true or not.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256