我很清楚difference between class and struct,但是我很难权威地说出这个定义是否明确:
// declare foo (struct)
struct foo;
// define foo (class)
class foo {
};
// instance of foo, claiming to be a struct again! Well defined?
struct foo bar;
// mixing class and struct like this upsets at least one compiler (names are mangled differently)
const foo& test() {
return bar;
}
int main() {
test();
return 0;
}
如果这是未定义的行为,有人可以指向权威(即ISO的章节和经文)参考吗?
处理此问题的编译器(Carbide 2.7)相对较旧,我尝试过的所有其他编译器对此非常满意,但显然没有任何证据。
我的直觉是这应该是未定义的行为,但我无法找到任何证实这一点,我很惊讶没有GCC版本或Comeau如此警告它。
答案 0 :(得分:11)
在我看来它是定义的行为。特别是,§9.1/ 2说:
仅由
class-key identifier ;
组成的声明要么重新声明 当前范围中的名称或标识符的前向声明作为类名。它将类名引入当前范围。
标准区分了在定义类时使用class
,struct
或union
,但在这里,谈论声明,没有做出这样的区分 - 使用一个class-key
等同于任何其他。
答案 1 :(得分:5)
从技术上讲,根据语言标准,代码是可以的。但是,由于至少有一个最受欢迎的编译器会对此发出警告,因此在实践中不起作用。
“从理论上讲,理论与实践之间没有区别。在实践中,有。”
答案 2 :(得分:4)
从Warning C4099: type name first seen using 'class' now seen using 'struct' (MS VS 2k8)看来,至少有些编译器会根据所使用的关键字进行不同的编辑,因此即使技术上允许,也最好不要依赖它(我无法找到确认参考)。
答案 3 :(得分:2)
在C ++中,struct是一个类。具体做法是:
结构是一个定义的类 类密钥
struct
。 (ISO / IEC FDIS 14882:1998(E)9-4)
这意味着您的类已定义 struct
,绝对不是结构。因此,使用struct class-key的前向声明是错误的。我不知道规范的任何部分允许前向声明使用明显错误的类键。我确信有问题的宽松编译器能够平等地处理结构和类,并且正在掩盖不正确的声明。在这种情况下,编译器可能不需要出错,但也不应该是意外的。
答案 4 :(得分:0)
根据C标准,我不知道这是否是未定义的(或任何其他非严格符合的类别),但我知道如果你有两个翻译单位不同意是否类型'foo'被声明为'class'或'struct',如下所示:
struct foo;
void f(foo&) { ... }
class foo { ... };
void f(foo&);
void g()
{
foo x;
f(x);
}
然后,至少一些编译器(特别是MSVC ++)会在每个翻译单元中以不同方式破坏f
的名称,因此TU 1中f
的定义不满足{{1}的引用在TU 2中你得到一个链接错误。如果您有一个定义类f
的标题A.h
并且需要引用类A
,B
和C
,那么现实生活就会出现这种情况。它们的前向声明就足够了(所以它非常明智地不包括D
等) - 你最好使用与实际定义相同的前向声明的关键字!
答案 5 :(得分:0)
MSVC10会发出警告,警告页面会指出将使用定义中给出的类型。