Is using typeid on a forward declared type undefined behavior?

c++, c++11, standards

Solution

When I compile your code with:

g++ foo.cpp main.cpp -o main

I get:

main.cpp: In function ‘int main()’:
main.cpp:12:52: error: invalid use of incomplete type ‘struct foo’
main.cpp:4:8: error: forward declaration of ‘struct foo’

That agrees with my interpretation of the standard, that you can't apply `typeid` to an incomplete type — and `a_ref_foo` is of an incomplete type, since the full definition of the type `foo` is not visible. `main.cpp` (with the lines I added) is ill-formed, and a diagnostic is required.

Update :

I've reproduced the issue with Visual Studio 2010 Express. Even with language extensions disabled, this trivial program:

#include <typeinfo>

struct foo;

int main()
{
  typeid (foo);
  return 0;
}

compiled with no diagnostic messages. With gcc 4.7, I get:

main.cpp: In function ‘int main()’:
main.cpp:7:14: error: invalid use of incomplete type ‘struct foo’
main.cpp:3:8: error: forward declaration of ‘struct foo’

The same rule:

If the type of the expression is a class type, the class shall be completely-defined.

appears in the 1998, 2003, and 2012 versions of the ISO C++ standard.

Looks like a bug in Visual Studio. (If somebody would like to report this to Microsoft, go ahead.)

Problem

Am I reading the standard correctly in `5.2.8.3: ... If the type of the expression is a class type, the class shall be completely-defined.` If the type is not "completely-defined" does that mean the following program is undefined? foo.cpp: ``` struct foo { virtual void a(){} }; struct bar : foo { virtual void a(){} }; bar abar; foo& get_some_foo() { return abar; } ``` main.cpp: ``` #include <iostream> #include <typeinfo> struct foo; foo& get_some_foo(); int main() { foo& a_ref_foo(get_some_foo()); std::cout << "a_ref_foo typeid name: " << typeid(a_ref_foo).name() << std::endl; return 0; } ``` MSVC10 outputs: `a_ref_foo typeid name: struct foo'

Original source