2

I have recently noticed an strange valid C/C++ expression in GCC/Clang which I have never seen before. Here is the example in C++, but similar expression works in C too:

int main(){
    int z = 5;
    auto x = ({z > 3 ? 3 : 2;}); // <-- expression
    std::cout << x;
}

What it does is somehow obvious, but I like to know what it is called. Since it does not worth in MSVC, I guess it is a non-standard extension. But is there anything that works for MSVC too? especially in C?

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Afshin
  • 8,839
  • 1
  • 18
  • 53
  • 8
    It's a GCC extension: [Statement Exprs](https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html#Statement-Exprs). It seems an unnecessary usage of it in this case. (It could have been written as `auto x = (z > 3 ? 3 : 2);` without any nasty extensions.) – Ian Abbott Jun 07 '21 at 14:48
  • What @IanAbbott said. With `-Wpendantic` I get a warning: `warning: ISO C++ forbids braced-groups within expressions [-Wpedantic]` – Fred Larson Jun 07 '21 at 14:50
  • @IanAbbott yea, I know it is unnecessary, I just wanted to write a sample code with it. I saw its usage in `max()` macro, but not in that page :D – Afshin Jun 07 '21 at 14:53
  • 1
    It is mostly used in macros defined with parameters when the programmer wishes to avoid the parameters being expanded more than once. – Ian Abbott Jun 07 '21 at 14:57
  • 1
    Does this answer your question? [Use of ({ ... }) brackets in macros to swallow the semicolon](https://stackoverflow.com/questions/5409694/use-of-brackets-in-macros-to-swallow-the-semicolon) – phuclv Jun 07 '21 at 15:03
  • 1
    [In what versions of C is a block inside parenthesis used to return a value valid?](https://stackoverflow.com/q/1635549/995714), [Use of ({ … }) brackets in macros to swallow the semicolon](https://stackoverflow.com/q/5409694/995714) – phuclv Jun 07 '21 at 15:03
  • For `max()` it can be used with another GCC extension `typeof` as shown in [Typeof](https://gcc.gnu.org/onlinedocs/gcc/Typeof.html). In the `max(a,b)` macro example given there, the statement expr and typeof extensions are used to define local variables with the same types as the parameters and initialized to the values of the parameters. That way, the parameters are only expanded once, and the local variables are accessed more than once to determine the maximum value. – Ian Abbott Jun 07 '21 at 15:05
  • I learned something new about this .. I thought it was named a tenary operation :) – Sorenp Jun 07 '21 at 15:28
  • C++ has a portable way to include statements in expression contexts; an immediately-evaluated lambda: `auto z = []{ if (z>3) return 3; return 2; }()`. – MSalters Jun 07 '21 at 19:16

2 Answers2

4

It's called statement expr, used in GCC. Your expression ({z > 3 ? 3 : 2;}) can be translated to

if (z > 3) {x = 3;} else {x = 2;}

From documentation:

A compound statement enclosed in parentheses may appear as an expression in GNU C. This allows you to use loops, switches, and local variables within an expression.

In other word, it provides the ability to put a compound statement in an expression position.

Related post :

Afshin
  • 8,839
  • 1
  • 18
  • 53
silverfox
  • 1,568
  • 10
  • 27
  • 1
    But given that `z > 3 ? 3 : 2` is a valid expression, the _statement expression_ syntax is not necessary here I think. – Clifford Jun 07 '21 at 17:02
0

It is called conditional operator . Return will be depend on condition either condition is true or false.

But in this case: auto x = ({z > 3 ? 3 : 2;}); // <-- expression

if Z is greater than 3 returns 3 otherwise 2.

Basic syntax : Expression1? expression2: expression3;

  • The _"strange"_ thing here is not the ternary `?:` operator, but the `{...}` braces and the semi-colon. – Clifford Jun 07 '21 at 17:01