6
main()

{

       int a=10,b=30,c=0;

       if( c =({a+b;b-a;})) 
       {
          printf("%d",c);
       }

}

why the construct ({;}) is legal in C and why it returns the last statement value as the result of the expression ( why it work similar to comma operator)?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
bare_metal
  • 1,134
  • 9
  • 20
  • Looks like a dup of [Are compund statements (blocks) surrounded by parens expressions in ANSI C?](http://stackoverflow.com/questions/1238016/are-compund-statements-blocks-surrounded-by-parens-expressions-in-ansi-c) – Shafik Yaghmour Sep 02 '14 at 09:40

2 Answers2

15

It is not legal standard C99, but it is a very useful GCC extension, called statement-exprs (a parenthesized brace compound statement ending by some expression).

IIRC, some other compilers support that extension, e.g. Clang/LLVM

Statement expressions are much more useful when they contain control flow changes and side-effects, like:

 c = 2*({while (a>0) a--,b--; a+b;});

However, in your particular case, you could just use the comma operator

 if (c=(a+b,b-a))

Since a+b does not have any side effect, I guess that an optimizing compiler could handle that as

 if (c=b-a)

GCC provides other useful extensions, notably local labels using __label__ and label as values with computed gotos (very useful in threaded interpreters ...). I don't know exactly why they have not been standardized. I wish that they would.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • `goto` is bad enough as is, we don't want to be encouraging it by allowing it to be used with a variable destination! – M.M Sep 02 '14 at 05:25
  • 1
    Sometimes computed goto is really useful (e.g. inside a threaded bytecode interpreter). Some code (e.g. bytecode interpreters like file `byterun/interp.c` of the Ocaml compiler) runs 30% faster when using computed gotos. – Basile Starynkevitch Sep 02 '14 at 05:30
1
main()
  {

   int a=10,b=30,c=0;

   if( c =({a+b;b-a;})) 
   {
      printf("%d",c);
   }

  }

Here,{a+b;b-a;} is one scope.In this you have written 2 statements.This is actually treated as

   {
    c=a+b;
    c=b-a;
   }

Initially c value is 40 because of a+b. Again c is modified by b-a. To prove this consider following three cases..

(1).

 if(c=({(a=a+b);;}))
   {
      printf("%d\n",c);
      printf("%d\n",a);
   }

Here o/p is c=40 and a=40;Because at end of scope (i.e) in last statement is dummy (;). so,c=a+b is o/p. (2)

   if(c=({(a=a+b);b-a;}))
   {
      printf("%d\n",c);
      printf("%d\n",a);
   }

Here o/p is c=-10, a=40. Because last statement is b-a. this value is assigned to c. (3) main() {

    int a=10,b=30,c=0;
    if(c=({(a=a+b);0;}))
      {
       printf("%d\n",c);
       printf("%d\n",a);
      }
     printf("%d\n",c);
    }

Here o/p is c=0 only.If is not executed ,Because of last statement is 0;

C follows procedure oriented.And associativity of () is left to right.

Anbu.Sankar
  • 1,326
  • 8
  • 15