10

如果类型不是“完全定义的”,我是否正确阅读了标准,5.2.8.3: ... If the type of the expression is a class type, the class shall be completely-defined. 这是否意味着以下程序未定义?

foo.cpp:

struct foo
{
  virtual void a(){}
};

struct bar : foo
{
  virtual void a(){}
};

bar abar;

foo& get_some_foo()
{
  return abar;
}

主.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 输出:`a_ref_foo typeid name: struct foo'

4

3 回答 3

13

当我编译你的代码时:

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

我得到:

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’

这与我对标准的解释一致,即您不能应用于typeid不完整的类型——并且a_ref_foo是不完整的类型,因为类型的完整定义foo是不可见的。main.cpp(我添加的行)格式不正确,需要进行诊断。

更新 :

我已经用 Visual Studio 2010 Express 重现了这个问题。即使禁用了语言扩展,这个简单的程序:

#include <typeinfo>

struct foo;

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

编译时没有诊断消息。使用 gcc 4.7,我得到:

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’

相同的规则:

如果表达式的类型是类类型,则类应该是完全定义的。

出现在 ISO C++ 标准的 1998、2003 和 2012 版本中。

看起来像 Visual Studio 中的错误。(如果有人想将此情况报告给 Microsoft,请继续。)

于 2012-07-04T02:14:04.250 回答
8

是的,该程序格式错误(而不是导致未定义的行为)。

如果你想知道为什么,那么你应该认为这typeid是一个单一的运算符,但它对于多态类型的语义与非多态类型的语义完全不同。特别是,如果foo是多态的(至少有一个虚函数,那么typeid将产生对实际类型type_info的对象的引用(在这种情况下),而如果该类型没有任何虚函数,那么它将返回对对象的引用对于表达式的静态类型(在这种情况下)。bartype_infofoo

为了让编译器生成适当的代码,编译器必须知道在使用的地方typeid这两种情况中的哪一种适用。如果类型不完整,则编译器不会提供该信息。

于 2012-07-04T02:59:46.837 回答
0

您的程序是完全正确的,因为函数 get_some_foobar是全局的。sobar是完全定义的,但是如果定义了 in 的变体barmain.cpp那么在 typeid 中作为参数使用,否则编译时会报错。

于 2012-07-04T00:50:14.203 回答