169

What could this possibly mean in C++11?

struct : bar {} foo {};
Tony Delroy
  • 102,968
  • 15
  • 177
  • 252
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055

2 Answers2

263

First, we'll take a bog-standard abstract UDT (User-Defined Type):

struct foo { virtual void f() = 0; }; // normal abstract type
foo obj;
// error: cannot declare variable 'obj' to be of abstract type 'foo'

Let's also recall that we can instantiate the UDT at the same time that we define it:

struct foo { foo() { cout << "!"; } };          // just a definition

struct foo { foo() { cout << "!"; } } instance; // so much more
// Output: "!"

Let's combine the examples, and recall that we can define a UDT that has no name:

struct { virtual void f() = 0; } instance; // unnamed abstract type
// error: cannot declare variable 'instance' to be of abstract type '<anonymous struct>'

We don't need the proof about the anonymous UDT any more, so we can lose the pure virtual function. Also renaming instance to foo, we're left with:

struct {} foo;

Getting close.


Now, what if this anonymous UDT were to derive from some base?

struct bar {};       // base UDT
struct : bar {} foo; // anonymous derived UDT, and instance thereof

Finally, C++11 introduces extended initialisers, such that we can do confusing things like this:

int x{0};

And this:

int x{};

And, finally, this:

struct : bar {} foo {};

This is an unnamed struct deriving from bar, instantiated as foo with a blank initializer.

rubenvb
  • 74,642
  • 33
  • 187
  • 332
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 4
    @stijn: [Though it's still probably a smart decision ;)] – Lightness Races in Orbit Aug 15 '11 at 16:48
  • 12
    I know that negative comments about a programming language should be avoided, and maybe it is a bit off topic here. But I do not understand why C++0x is becoming an even more complex language than C++ is. Who wants that? What are the advantages of a programming language that is becoming more and more cryptic? This declaration is IMHO yet another example of this. I have been using C++ for many years and I still have difficulties to master this language. – Giorgio Aug 15 '11 at 16:52
  • 27
    @Giorgio: Why is this a problem? What exactly scares you? The described construction is a fringe case that's allowed by the language and follows naturally from its core concepts, there's nothing wrong with it. It's also of very limited utility. You will never have to use it. However, it's syntactically logical and doesn't collide or conflict with anything. So, why would this be an argument *against* a language, especially one which exceptionally well designed? – Kerrek SB Aug 15 '11 at 16:55
  • 13
    @Giorgio -- the wonderful part is that the situation is exactly the opposite; c++0x is adding many so much awaited powerful facilities without being cryptic or too ugly; you want cryptic? -- check out Perl. This example here nowhere nearly approaches the title of cryptic. – Gene Bushuyev Aug 15 '11 at 16:57
  • 19
    @Kerrek SB I think C++ (and now C++0x) has simply too many different concepts and learning the syntax and semantics is difficult. Each programmer (I am one of them) ends up using a subset of the language because there are too many different ways of doing the same thing. I do not think C++ is well-designed. There are many ad-hoc features and certain fundamental things like a robust module (import / export) mechanism are missing (still using old #include from C). I think the C++0x effort should aim at making C++ smaller and easier to use, not bigger. – Giorgio Aug 15 '11 at 17:02
  • @Gene Bushuyev I agree with you on Perl. I bought a book, tried it out, but after the first small project I gave up. – Giorgio Aug 15 '11 at 17:04
  • 31
    @Giorgio: To be honest, any such effort would have to work on rebuilding C++ from the ground up, i.e. _creating a new language_. And that **has** been done... many times. – Lightness Races in Orbit Aug 15 '11 at 17:04
  • 5
    @Tomalak Geret'kal: Maybe you are right, Java is perhaps one such example. Anyway, after three years on a C++ project, I still happen to find code written by colleagues using some construct I haven't encountered before (I started using C++ back in the early nineties so I am not a newcomer). I think a programming language should not have too many built-in idioms. So I wonder why new features (like these new initializers) are being added all the time. Even if new features may be interesting I find this continuous extension rather confusing. – Giorgio Aug 15 '11 at 17:14
  • 7
    @Giorgio: I actually find C++ semantics to be quite simple. I do agree that the syntax is a bit unwieldy, but that's because C compatibility was a design goal, and thus had to preserve a lot of the syntax. I have to disagree with your claim that C++ has a lot of ad-hoc features. The C++ committee typically only add features that are highly general and solves many problems as opposed to features that solve only a specific problem, so they tend to be very thoroughly discussed and drawn out. – In silico Aug 15 '11 at 17:21
  • 4
    @In silico: Yes but eventually one should stop adding new features, otherwise programmers will start using only a subset of the language. For a large project it is not good if different developers use different subsets / dialects of the language: It make code reviewing and bug fixing less efficient. I think other programming languages also suffer from this problem. For example, a colleague of mine was complaining about Haskell being too feature-rich and therefore difficult for a programmer to master. – Giorgio Aug 15 '11 at 17:30
  • 8
    @Giorgio: Well if you don't need to use all the features... then don't use all of them. It's the same type of criticism I hear for or . It may be true that you use only a subset of features, but *[that subset of features will not be the same for everyone](http://www.joelonsoftware.com/articles/fog0000000020.html)*. For every person that praises something for not being bloated, there will be someone else who will lambast it for not having that one feature they need to get the job done. – In silico Aug 15 '11 at 17:44
  • 2
    @In silico: Yes the discussion could get very general (that's why I mentioned Haskell to make it clear that this is not only a C++ problem). The fact that the subset is not the same for everyone is exactly the problem: I work in a project with more than 20 developers, and I have to review or fix code written by others. So I have to learn 20 different dialects of C++! It makes the whole development less efficient and more error-prone. – Giorgio Aug 15 '11 at 17:52
  • 1
    @Giorgio: I have seen very good reasons for most of the new features in C++11. Regarding this one in particular, of [these three pieces of code](http://ideone.com/PSsHP), do you not find the first much easier to read? If so, does that not make the case that at least *this* feature has made the code *easier* to understand, not more difficult? – Benjamin Lindley Aug 15 '11 at 18:01
  • 9
    @Giorgio, In silico: I agree with many of Giorgio's points. Take the "large project" objection, for example: To use the language effectively, you should be able to apply ALL of its features. So you have two choices: You hire experts with approx. same skills (expensive), or you restrict yourself to "simple" features and stick with the team you've got (ineffective) . Well, the 3rd option is the usually taken: Don't use C++... – Paul Michalik Aug 15 '11 at 18:04
  • 1
    @Giorgio: __1)__ C++ is as old as the stone age and got wielded to for a quarter century. __2)__ It was designed iteratively, with it's creator (and later the std committee) learning as their were going, changing focus over time. __3)__ It doesn't tie you into one paradigm, but allows you to freely mingle them to a powerful mixture, and that freedom comes with the ability to abuse it. However, the other day, Jerry Coffin gave [an alternative answer](http://chat.stackoverflow.com/transcript/message/1243343#1243343) to the same question, which is at least as good as all my rationales combined. – sbi Aug 15 '11 at 18:09
  • Folks, can you move this discussion over to a chat room? Thanks. – Kev Aug 15 '11 at 20:10
  • 1
    @TomalakGeret'kal: All is fine, but what is the point of discussing abstract class and virtual function in it? There seems no relation between this and the question (and the final answer). – Nawaz Oct 20 '11 at 12:00
  • 1
    @Nawaz: Just so that I can get GCC to print the ``. Notice, afterwards, "We don't need the proof about the anonymous UDT any more, so we can lose the pure virtual function" – Lightness Races in Orbit Oct 20 '11 at 13:00
  • @TomalakGeret'kal: That makes sense. But can't give another `+1` as I've already given one on the very first day. – Nawaz Oct 20 '11 at 13:19
  • @Nawaz: Aww, always one of my most loyal fans :P:P – Lightness Races in Orbit Oct 20 '11 at 13:24
  • @TomalakGeret'kal: Hehe... :D – Nawaz Oct 20 '11 at 14:05
  • 1
    void main() { MyClass t(); } -- function invocation not object instantiation with default constructor. More crazy C++ for you guys. – Philluminati Feb 14 '12 at 13:30
  • 3
    @Philluminati: That's not C++. And, yes, we know about the [most vexing parse](http://en.wikipedia.org/wiki/Most_vexing_parse), something asked about on SO almost daily. :) (Although that's a declaration, not an invocation.) – Lightness Races in Orbit Feb 14 '12 at 15:25
  • There is funny bug in GCC 4.5 with it: struct A { std::string i; }; int main() { struct : A { int j; } B { }; assert(B.j == 0); // B.j != 0 } Proof: http://ideone.com/C00pEg – NN_ Dec 02 '12 at 17:10
  • @NN_: Failing default-initialization? – Lightness Races in Orbit Dec 02 '12 at 23:56
  • what is the use of this kind of initialization in real time programming ?I don't think anyone has ever used this kind of concept . – Viku Dec 28 '12 at 08:13
  • Just bumped into your answer, super strange syntax indeed. However, if I just try `struct {};` I'm getting a warning: `warning: ISO C++ prohibits anonymous structs [-Wpedantic]`. Then an error `error: abstract declarator < anonymous > used as declaration`. Why does your code doesn't emit such warning? Aren't you still define an anonymous `struct` (derived from `bar`), the only difference being that you use it in defining a variable? – vsoftco Nov 21 '15 at 00:09
  • @vsoftco: I gave my instance a name (`foo`); you did not. And without the type name I guess it's always an instance declaration too. An instance without a name is illegal. – Lightness Races in Orbit Nov 21 '15 at 00:15
  • Hmmm I guess so. +1 anyway for coming up with this. Such gems should be collected somewhere ;) Reminds me of [this](http://stackoverflow.com/q/33764533/3093378), although the latter is less "extreme". – vsoftco Nov 21 '15 at 00:16
107

This defines:

  • an anonymous struct,
  • which is derived publicly from bar
  • which (anonymously) defines nothing else but what it derived from bar
  • and finally, an instance, called "foo" is created,
  • with an empty initializer list

struct : bar {} foo {};
Frunsi
  • 7,099
  • 5
  • 36
  • 42