3
#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");
}

Output is "float". So i don't understand why sizeof((x==2)?f:i) always return 4. I think declaration is missing variable at (x==2)?f:i; But it always returns 4(sizeof(f)).

Can you help me! This is the first programming language I learn. I know this question very stupid but with me very hard. Thanks for spends your time:) Have a good day ;)

And the first time I try to use Stackoverflow, maybe have some mistakes. Hope you forgive me

Cid
  • 14,968
  • 4
  • 30
  • 45
Stack
  • 111
  • 6
  • The expression `a ? b : c` has **one** definite type that does not depend on `a`: it depends only on `b` and `c` and, that **one** type, is determined at compilation time. `0 ? 42 : 3.14` has type `double` and value `3.14`, `1 ? 42 : 3.14` has type `double` and value `42.0` – pmg Mar 12 '20 at 15:06
  • This is all clear, but I still wonder, what the OP _wants_ to achieve... I briefly thought I knew it, but.. – Ctx Mar 12 '20 at 15:07
  • Thanks for your answer. I have one more question is if the expression not depend on a, so how do you know the expression depends on b or c? – Stack Mar 12 '20 at 15:12
  • 1
    @HoangLam not only "b or c" but "b and c". It follows the implicit conversion rules and has the same type as for example `b + c` – Ctx Mar 12 '20 at 15:13

1 Answers1

7

A type of expression is deduced statically, at compile time.

So the type and size of (x == 2) ? f : i expression is known at compile time and will not change at runtime no matter what variable values are.

The type of result of ternary operator in this case is determined using usual arithmetic conversions (C99 6.5.15p5 and C99 6.3.1.8p1). The type of (x == 2) ? f : i is determined as float.

The whole sizeof((x == 2) ? f : i) is evaluated at compile time and is equal to sizeof(float).

You could move x == 2 out of sizeof so that it is evaluated at runtime:

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

Also note that it may happen that sizeof(short int) == sizeof(float).

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • thanks for your answer, I finally understood the problem :) – Stack Mar 12 '20 at 15:21
  • Can you help me one more time :( when a ternary operator has Expression 1, not a logical expression. I mean Expression 1 not return true or false. But variable always has a value from Expression 2 or Expression 3. Like `int y = 1, x = 0;` `int l = (y++, x++) ? y : x` => `l=1` and`int l = (y++, x++) ? x: y` =>`l=2` So,how i find out correct value of the variable – Stack Mar 13 '20 at 00:42
  • What is "Expression 1", 2, 3? To do `this`, remove the space after the \` backtick. ` space` and `space`. Well, in `(y++, x++) ? y : x` then `x` is incremented and returned, so it's 1, in `(y++, x++) ? x : y` then `y` is incremented and returned. I do not follow. Maybe `(y++, x++) ? y : x` is like to `y++; if (x) { x++; y; } else { x++; x; }` – KamilCuk Mar 13 '20 at 00:46
  • **Variable = Expression 1 ? Expression 2 : Expression 3** – Stack Mar 13 '20 at 00:48
  • Any value different then 0 is true. A value equal to zero is false. `(y++, x++)` is 1, if value of `x` is different then 0. Maybe some links [comma operator](https://en.cppreference.com/w/c/language/operator_other) and [if statement](https://en.cppreference.com/w/c/language/if) – KamilCuk Mar 13 '20 at 00:49
  • So sorry, the first time I try to use Stackoverflow. I will practice more – Stack Mar 13 '20 at 00:49
  • Yep, i understood, _Any value different then 0 is true. A value equal to zero is false_ it means `Expression1` maybe logic or not logic. If `Expression1` different then 0 is true, equal 0 is false, right? – Stack Mar 13 '20 at 00:56
  • 1
    Right. There is no such thing as "logic expression". The result of expression is literally compared with 0. For example [comparision operators like == or !=](https://en.cppreference.com/w/c/language/operator_comparison) just return an `int` with the value `0` or `1`. – KamilCuk Mar 13 '20 at 00:58
  • thank you so much, C is the first language and there is so much to learn with me. Have a good day <3 – Stack Mar 13 '20 at 01:03
  • _For example comparision operators like == or != just return an int with the value 0 or 1_ and Ternary Operator will return an `float` if values of `expression2` and `expression3` less than `float`-type or `double` if more than. it's right? I realized through the examples:) – Stack Mar 13 '20 at 01:09
  • No or yes, depending on what "less then" means. The usual arithmetic conversions [cppreference](https://en.cppreference.com/w/c/language/conversion) and in [C99 6.3.1.8](https://port70.net/~nsz/c/c99/n1256.html#6.3.1.8). In `(x == 2) ? f : i` the variable `f` has type `float` and variable `i` has type `i`. Now on `f` and `i` the "usual arithmetic conversion" is performed, which say (from cppreference) `if one operand is float the other operand is implicitly converted as follows: integer type to float`. So `i` is converted to `float` and the result of `(x == 2) ? f : i` becomes `float`. – KamilCuk Mar 13 '20 at 01:12
  • 1
    Och I guess what you mean by "less then" - the "conversion rank" from integer promotions. But conversion rank is only for integer types - floating point types do not have conversion rank. But kind-of yes, it works as-if `float` would have greater conversion rank then all integers. – KamilCuk Mar 13 '20 at 01:16
  • last night i try with two `short int` , `(x == 2) ? f : i` mean `f` and `i` is `short int type`, so result always = 4 `float`. or Or maybe I misunderstood this problem :( – Stack Mar 13 '20 at 01:18
  • 1
    When both `f` and `i` are `short int`, then they while _usual arithmetic conversions_ they both first undergo implicit _integer promotions_, which converts them to both `int` type. [From cppreference](https://en.cppreference.com/w/c/language/conversion) the `4) Otherwise, both operands are integers. Both operands undergo integer promotions` and below `Integer promotion is the implicit conversion of a value of any integer type with rank less or equal to rank of int .... to int or unsigned int`. So it becomes `sizeof(int)`. And most probably `sizeof(int)` = `sizeof(float)` on your platform. – KamilCuk Mar 13 '20 at 01:34