Why ternary operator does not support blocks?
Asked Answered
D

9

5

Why the ternary operator does not have blocks? In other words, why the following code does not work and reports error for {} braces?

int main()
{
    int i = 1;
    (i==1)?{printf("Hello\n")}:{printf("World\n")};
    return 0;
}

EDIT

Perhaps the question is misunderstood. It was: why blocks are not supported? Why only single expression?

Why this is not allowed to work?

int main()
{
    int i = 1;
    (i==1)?{printf("Hello\n");printf("World\n");}:{printf("Bye\n");printf("World\n");};
    return 0;
}

One reason could be that ternary are often used for conditional assignment on left side and blocks will have no such returns or it will get confusing with multiple statements inside block.

Dyewood answered 8/7, 2015 at 18:26 Comment(5)
Because there is a need to return a value. But GCC can like this (i==1)?({printf("Hello\n");}:({printf("World\n");});Nogood
If your intention is to use multiple statements, you can use function calls in ternary operatorsHereto
Because this is a terrible use of the ternary operator.Mussman
I think the compiler only allows one expression may be because of two reason.. 1. It understands it as a boolean or 1/0 expression & multiple statement may hamper that 2. It is not good for readability..for this we have if-else which is more readable I guessHereto
@BLUEPIXY, my gcc compiler did not like the posted code nor your example line. amongst other things, this warning: "... ISO C forbids braced-groups within expressions [-Wpedantic]"Jacquiline
L
10

To quote C11 standard, chapter §6.5.15, the syntax of the conditional operator is

conditional-expression:
    logical-OR-expression
    logical-OR-expression ? expression : conditional-expression

Where, the second and third operands are expression, not statements.

Just to elaborate,

One of the following shall hold for the second and third operands:
— both operands have arithmetic type;
— both operands have the same structure or union type;
— both operands have void type;
— both operands are pointers to qualified or unqualified versions of compatible types;
— one operand is a pointer and the other is a null pointer constant; or
— one operand is a pointer to an object type and the other is a pointer to a qualified or unqualified version of void.


Edit:

To answer the question

Why only single expression?

again, quoting the standard,

....the result is the value of the second or third operand (whichever is evaluated), converted to the type described below.

Block of statements, will not give a value. The evaluation of an expression can.

Lamplighter answered 8/7, 2015 at 18:30 Comment(0)
G
5

The ternary operator consists of expressions. There is no such a kind of expression that uses braces.

You can write simply

( i == 1 ) ? printf("Hello\n") : printf("World\n");

It seems that the only case when braces can be present in an expression is the use of a compound literal. For example

struct A { int x; int y; } a = { 1, 2 };

a = a.x < a.y ? ( struct A ){ a.y, a.x } : ( struct A ){ ++a.x, --a.y }; 

As for this statement

(i==1)?{printf("Hello\n");printf("World\n");}:{printf("Bye\n");printf("World\n");};

then it can be rewritten the following way using the comma operator

i == 1 ? ( printf("Hello\n"), printf("World\n") ) : ( printf("Bye\n"), printf("World\n") );

Or even like

i == 1 ? printf("Hello\n"), printf("World\n") : ( printf("Bye\n"), printf("World\n") );

Shortly answering your question if you need a code block then use the if-else statement instead of the ternary operator. Though the if-else statement may not be used in expressions. On the other hand it is desirable for readability of the code that expressions would not be too compound.

As any operator the ternary operator is used in expressions and returns some evaluated value. For example as an expression it can be used as initializer or in assignments.

Grape answered 8/7, 2015 at 18:29 Comment(4)
What about the compound literal operator () {}?Visser
@Visser Thanks. I included an example of using a compound literal.Grape
For mentioning compound literals +1.Huberman
This example worked fine for Postman, where I could not create an if statement i == 1 ? ( printf("Hello\n"), printf("World\n") ) : ( printf("Bye\n"), printf("World\n") );. Thank you!Repairman
M
3

The ternary operator expects an expression for each part, and {...} is not an expression, but a statement.

To expand on your edit, the result of a ternary operator is an expression (but not an lvalue as you suggest), and statement blocks can't evaluate to a value.

For example, this doesn't make sense:

int x = (i==1)?{printf("Hello\n");printf("World\n");}:{printf("Bye\n");printf("World\n");};

But you could do this:

int x = (i==1)?(printf("Hello\n"), printf("World\n")):(printf("Bye\n"), printf("World\n"));

In which case, the comma operator would cause the last value in each subexpression to be returned.

Marcus answered 8/7, 2015 at 18:30 Comment(3)
last value in each subexpression to be returned? But I am getting Hello World and not World World. Did I understand incorrectly?Dyewood
@InsaneCoder notice the second "operand", as x will be TRUE.Lamplighter
Because the conditional part of the ternary operator is true, only the second part is evaluated. So printf("Hello\n") and printf("World\n") are both run, and the return value of the latter will be assigned to x.Marcus
S
2

Operators in C language can only be used in expressions. There's no such thing as "block" in an expression. In C language blocks are elements of higher-level syntactic structure. Blocks exists at the level of statements. Expression can be used in a statement. But statement cannot become an expression (or be used inside an expression).

Your particular example can be rewritten in terms of expressions

i == 1 ?
  printf("Hello\n"), printf("World\n") :
  printf("Bye\n"), printf("World\n");

without any need for {}.

(See Uses of C comma operator for extra information)

Speckle answered 8/7, 2015 at 18:40 Comment(1)
@AnT It is a wrong using of the conditional operator. See my answer.:)Grape
H
0

Yes only one expression is possible in ternary operators..You have to use if-else for multiple statements. Ternary operators takes one expression only in each slot although you can call two different functions in ternary operator

#include <stdio.h>

void a(){
 printf("Hello\n");
 printf("Hi\n");

}

void b(){
  printf("Hi\n");
  printf("Hello\n");
}

int main()
 {
int i = 1;
(i == 1) ? a() : b();
return 0;
}
Hereto answered 8/7, 2015 at 18:30 Comment(1)
There is actually no statement at all allowed. As you already wrote, there are only expressions allowed. Simple reason: it is an operator, thus it is also "just" an expression.Tertullian
A
0

The ternary operator is not meant to be used as a control structure, meaning it's not meant to control execution of statements. It's simply a way to choose which of two or more expressions will be evaluated.

As Sourav Ghosh has shown, the syntax of a conditional expression simply does not allow the operands of the ?: operator to be statements.

Appeasement answered 8/7, 2015 at 18:45 Comment(0)
P
0

This is not allowed because it makes no sense. The ternary operator is meant to return a value. What would that be for {} blocks? And then also there is another construct if () { } else { } that already serves the same purpose that you are trying to give to ? :. Doesn't this here look much nicer than the code that you posted?

int main(void)
{
    int i = 1;
    if (i==1) {
       printf("Hello\n");
       printf("World\n");
    } else {
       printf("Bye\n");
       printf("World\n");
    };
    return 0;
}
Prissy answered 8/7, 2015 at 20:8 Comment(0)
L
0

As others have noted, GCC allows statements to be used syntactically as expressions, but such a feature is not part of the C standard. Historically, the reason for this likely had to do with the fact that statements are allowed to declare variables, and many systems use the same stack to hold local variables and parameters as is used to hold temporary values used in expression evaluation. Allowing new variables to come into existence within the execution of a statement while still keeping old variables in view would add some complexity to the compiler [note that when a function is called within a new expression, new variables are created for that function, but the old values will be "out of view" until the called function returns and the new variables are destroyed].

That having been said, other features of C such as variable-length arrays require far more complexity than would the ability to embed statements in expressions, so the arguments in favor of that design are no longer as compelling as they were in the 1970s. Unfortunately, the fact that something was once a compelling reason not to include a feature in a language may cause it to forevermore be perceived that way, even if design considerations for today's compilers are nothing like those of the 1970s.

Legislatorial answered 9/7, 2015 at 22:47 Comment(0)
I
0

Why ternary operator does not support blocks?

For roughly the same reason that a bicycle does not support wings.

If you have two blocks of statements, and you want to execute one or the other based on a condition, there's a perfectly good way to do that: the if/else statement.

And if you have two expressions, and you want to evaluate one or the other based on a condition, that's what the ternary or ?: operator is for.

But asking the ?: operator to execute one or the other of two blocks of statements is asking it to do something it's not meant for. Continuing the jokey analogies, it's like asking, why can't a hammer drive screws?

This distinction — that if/else is for blocks of statements, and ?: is for expressions — flows out of C's fundamental distinction between expressions and statements. They're only partially integrated in C: you can turn any expression into a statement by putting a semicolon after it, but you can not, in general, use a statement as an expression. Why not? Well, partly because the syntax of the language doesn't permit it, and partly because there's no universal definition of what the value of a statement (or a block of statements) is.

Now, you can certainly imagine a language in which every statement has a well-defined value. In such a language, if/else and ?: would probably be fully interchangeable. And, in fact, some C compilers do implement this full integration of expressions and statements, as an extension — but it's an extension, not Standard C.

Indehiscent answered 29/8, 2022 at 15:10 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.