Here is a program that compiles without warning, for example. GNU C ++:
$ g++ -ot -Wall -pedantic -Wshadow t.cpp $ ./t.exe Calling barney::barney() Calling foo::operator()() Calling barney::barney()
But it does not fully compile on MSVC ++:
$ cl /EHsc t.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.30729.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. t.cpp t.cpp(17) : error C2380: type(s) preceding 'fred' (constructor with return type, or illegal redefinition of current class-name?) t.cpp(17) : error C2208: 'fred' : no members defined using this type
What else, when it compiles, the result is not what I would expect. Can someone shed some light on what would be the standard behavior for this code ?
There he is:
#include <iostream> using ::std::cerr; struct fred; struct foo { inline fred operator ()(); }; struct barney { barney() : v_(0) { cerr << "Calling barney::barney()\n"; } int v_; }; struct fred : public barney { foo fred; int joe; struct fred memfunc() { return fred(); } }; inline fred foo::operator ()() { cerr << "Calling foo::operator()()\n"; return fred(); } int main(int argc, const char *argv[]) { fred f; f.memfunc(); return 0; }
He outputs this:
Calling barney::barney() Calling foo::operator()() Calling barney::barney()
But I would expect this:
Calling barney::barney() Calling barney::barney()
Why am I getting the conclusion I am making? Is this standard behavior? If so, why, which sections of the standard are relevant?
In addition to the accepted answer, David Rodriguez gave an excellent answer, which states that in the standard, I'm allowed to declare a member named fred struct fred .
source share