Why ternary operator does not support blocks?

风格不统一 提交于 2019-12-12 13:12:25

问题


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.


回答1:


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.




回答2:


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 semss 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 readeability 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.




回答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.




回答4:


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)




回答5:


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;
}



回答6:


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.




回答7:


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;
}



回答8:


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.



来源:https://stackoverflow.com/questions/31300738/why-ternary-operator-does-not-support-blocks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!