0

I hasn't understand what compiler does here and why it's working c++ code

#include <cstdio>
int main()
{
    printf( ({  // (1)
                struct some_noize_struct {
                   // there may be another code
                };
                42;
                "abc";
              }) // (2)
            );

    return 0;
}

Type of expression between (1) and (2) braces is const char*. After some experimens i unrerstood that type of (1)-(2)-expression determined by last part.

Here is a sample code. It works on c++11 and later. http://cpp.sh/5tb47

My question: how it works.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • 3
    It's a [GCC extension](https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html). It does not work in standard C++. – HolyBlackCat Aug 04 '18 at 20:30
  • BTW this can be done in standard C++11 creating a lambda and invoking it immediately: `printf( ([&]{ struct some_noize_struct { /*... */ }; 42; return "abc"; }) );` – Matteo Italia Aug 04 '18 at 20:57
  • @HolyBlackCat, thank you. Really, msvc produces an error on this code. g++ with --Wpedantic produces warning: ISO C++ forbids braced-groups within expressions. – user3273943 Aug 04 '18 at 21:03

1 Answers1

3

As @HolyBlackCat explains, the code you listed uses a GCC compiler extension to C++ (and to C), while allows for compounds statements to be used as expressions.

In your printf() statement, you need to provide a const char* or const char* & expression as the first argument to the function, e.g. printf("hello") or printf(getenv("PATH")). The extension allows the interpretation of a curly-braced block as such an expression, using the last statement in the block. The block in your case is:

{ 
    struct some_noize_struct { 42 };
    42;
    "abc";
}

which has 3 statements. The last statement is the value of the entire expression, which means that what the printf() sees is essentially the same as if you had typed printf("abc").

This kind of code is not standard C++ (C++11 or any another version), nor is it standard C.

I suggest you write the maintainers of the "C++ Shell" website and ask them to display the exact compilation command-line they use, and/or make sure they use --std=c++11 to compile C++11 code - which it looks like they aren't doing.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
einpoklum
  • 118,144
  • 57
  • 340
  • 684