4

Why this compound statement as a sequence of statements enclosed by braces (in GNU C++) and inside parentheses does not appear to be a valid Statement expression.

// my second program in C++
#include <iostream>
using namespace std;

int main ()
{
  cout << "Hello World! ";
  ({cout << "I'm a C++ program";}); 

}

Compiler output:

 In function 'int main()':
8:32: error: use of deleted function 'std::basic_ostream<char>::basic_ostream(const std::basic_ostream<char>&)'
In file included from /usr/include/c++/4.9/iostream:39:0,
                 from 2:
/usr/include/c++/4.9/ostream:58:11: note: 'std::basic_ostream<char>::basic_ostream(const std::basic_ostream<char>&)' is implicitly deleted because the default definition would be ill-formed:
     class basic_ostream : virtual public basic_ios<_CharT, _Traits>
           ^
/usr/include/c++/4.9/ostream:58:11: error: use of deleted function 'std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)'
In file included from /usr/include/c++/4.9/ios:44:0,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from 2:
/usr/include/c++/4.9/bits/basic_ios.h:66:11: note: 'std::basic_ios<char>::basic_ios(const std::basic_ios<char>&)' is implicitly deleted because the default definition would be ill-formed:
     class basic_ios : public ios_base
           ^
In file included from /usr/include/c++/4.9/ios:42:0,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from 2:
/usr/include/c++/4.9/bits/ios_base.h:786:5: error: 'std::ios_base::ios_base(const std::ios_base&)' is private
     ios_base(const ios_base&);
     ^
In file included from /usr/include/c++/4.9/ios:44:0,
                 from /usr/include/c++/4.9/ostream:38,
                 from /usr/include/c++/4.9/iostream:39,
                 from 2:
/usr/include/c++/4.9/bits/basic_ios.h:66:11: error: within this context
     class basic_ios : public ios_base
           ^

I have found a good answer about 'statement expression' in What's this C++ syntax that puts a brace-surrounded block where an expression is expected?

K.Karamazen
  • 176
  • 1
  • 8
  • 4
    Aside: I hope this is not *actually* your second c++ program. You should learn more of the language before you learn compiler specific extensions. – cigien May 29 '20 at 18:40
  • 1
    @cigien: An expert in computer science generally might take up a new language and jump to extensions immediately. The question posed is sensible, and there is no reason to jump to conclusions about the asker. – Eric Postpischil May 29 '20 at 18:56
  • 1
    That comment could also be a joke, of course... – Nate Eldredge May 29 '20 at 18:58
  • 1
    @EricPostpischil That's fair. I meant that it might be easier to understand what the language extension is doing, if you know more about the language, but I suppose there's no harm in trying to understand the particular extension anyway. It's definitely a valid, and well asked question. – cigien May 29 '20 at 19:01
  • 1
    @NateEldredge Well, I was being serious, but I suppose the tone could have been less judgemental. I'll try and bear that in mind in the future. – cigien May 29 '20 at 19:02
  • Guys, it does not matter, the base example is from here: https://www.cplusplus.com/doc/tutorial/program_structure/ Very convenient site for testing examples. – K.Karamazen May 29 '20 at 19:07

1 Answers1

7

From the reference:

The last thing in the compound statement should be an expression followed by a semicolon; the value of this subexpression serves as the value of the entire construct.

and

In G++, the result value of a statement expression undergoes array and function pointer decay, and is returned by value to the enclosing expression.

This means in the expression:

({cout << "I'm a C++ program";}); 

the object std::cout is returned by value. This invokes the copy constructor of std::basic_ostream, which is deleted, and hence the error.

cigien
  • 57,834
  • 11
  • 73
  • 112
  • 1
    So, `({void(cout<<"I'm a C++ program");});` – jthill May 29 '20 at 19:25
  • 1
    @jthill Or just `({cout << "I'm a C++ program"; ; });`. But I think this is mostly an academic question, and the OP is not actually looking for a fix. – cigien May 29 '20 at 19:27
  • The question came up because I read a c++ wrapper for gnu prolog on GitHub and found 'statement expression' in it. That was a feature that I didn't use much in the past and I started testing it a bit. Coincidentally, I came across an unexpected error message. The explanation is a bit above my capabilities, but basically I understand that not everything works very simply. It will be enough for me to stick to simpler constructions. Good style to follow anyway. Thank you very much! – K.Karamazen May 29 '20 at 22:35
  • No worries, happy to help :) – cigien May 29 '20 at 22:45