-3

Consider this code:

#define SZIE 1024

printf("%\zu",SZIE<-1?1:0);

It will print '0'. This confuses me.

In my view, the signed number -1 shoulkd be converted to SIZE_MAX. The expression 1024 < SIZE_MAX is true, so I think "1" should be printed, but no.

I tried converting explicitly:

printf("%zu",SIZE<(size_t)-1?1:0);

It prints "1", which seems correct.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
cy1
  • 1
  • 4
    `SZIE` is not typed, it's simply text that will be replaced by the number `1024` by the preprocessor. So `SZIE<-1` is `1024<-1` which is obviously false – UnholySheep May 09 '23 at 15:06
  • Your ternary operator evaluates either to `0` or`1` which are both of type `int`. Your format specifier `%zu` is for arguments of type `size_t`. That does not match, causing undefined behaviour. `size_t` is likely to be larger than `int`. – Gerhardh May 09 '23 at 15:07
  • Why would there be `SIZE_T_MAX` involved anywhere? There is no variable of type `size_t` in your first snippet. – Gerhardh May 09 '23 at 15:08
  • `#define SIZE (1024U)` – Hans Passant May 09 '23 at 15:14
  • The conversion specifier `%zu` tells `printf` to *expect* a `size_t` as the corresponding argument, but it's up to you to make sure that that argument actually does have type `size_t`. The format string has no bearing at all on the type of the expression `SZIE<-1?1:0` or of any of the sub-expressions or constants within, nor does it cause any automatic type conversion of the `printf` arguments. – John Bollinger May 09 '23 at 15:18
  • I understand now. I made a stupid mistake. – cy1 May 09 '23 at 15:23
  • Given that comparison expressions already evaluate to 1 when true and to 0 when false, this could have been formulated without mentioning the ternary operator at all. Which makes the [question title](https://meta.stackexchange.com/a/388112/620615) awful. – user3840170 May 09 '23 at 15:34

3 Answers3

3

You defined a macro SZIE (I think you mean SIZE) for the integer constant 1024 of the type int.

#define SZIE 1024

So 1024 is not less than -1.

Moreover as the operands have the type int then and the result of the conditional operator has also the type int and you need to use the conversion specifier d instead of zu in the call of printf. And it seems there is a typo \z in the format string

printf("%\zu",SZIE<-1?1:0);

That is you need to write

printf("%d\n",SZIE<-1?1:0);

If you need to get the expected result you can write for example

printf("%d\n",( size_t )SZIE<-1?1:0);

Or it would be enough to introduce a constant of the type unsigned int like

#define SZIE 1024u

and write

printf("%d\n",SZIE<-1?1:0);

In this case due to the usual arithmetic conversions the expression -1 having the type int will be converted to the type unsigned int producing a big unsigned value.

Pay attention to that independent of the condition expression of the conditional operator its result in any case has the type int because the second and the third operands have the type int. And the condition expression itself has the type int and yields either 0 or 1.

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

1024, -1 and 0 are all ints so the result of the operator should be 0 since 1020 < -1 is false and the false value is therefore chosen.

When you do (size_t) -1 and convert the int to an unsigned type, it'll get the largest value possible for a size_t - which is larger than 1024 and therefore the truth value 1 is chosen.

Note that %zu is wrong in both cases since both 1 and 0 are still ints so the type of the operator is int and you should therefore use %d to print the result.

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
0

printf("%d\n",SZIE<-1?1:0); is equvakent to

if(SZIE < -1) printf("%d\n", 1);
else printf("%d\n", 0);

As your SZIE is 1024 the else part of if will be executed.

Generally ternry operator:

(condition) ? (value_if_condition_is_true) : (value_if_condition_is_false)

PS Your printf format string is wrong.

0___________
  • 60,014
  • 4
  • 34
  • 74