混合类和结构
我很清楚类之间的区别和结构</a>,但是我很难权威地说这是否定义良好:
// 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 甚至警告过这一点。
I'm well aware of the difference between class and struct, however I'm struggling to authoritatively say if this is well defined:
// 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;
}
If this is undefined behaviour can someone point me in the direction of an authoritative (i.e. chapter and verse from ISO) reference?
The compiler with problems handling this (Carbide 2.7) is relatively old and all the other compilers I've tried it on are perfectly happy with this, but clearly that doesn't prove anything.
My intuition was this ought to be undefined behaviour but I can't find anything to confirm this and I'm surprised that none of the GCC versions or Comeau so much as warned about it.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在我看来,这是定义的行为。特别是,§9.1/2 说:
该标准在定义类时区分使用
class
、struct
或union
,但这里讨论的是声明,没有这样的区别——使用一个class-key
与任何其他的都是等价的。It looks to me like it's defined behavior. In particular, §9.1/2 says:
The standard distinguishes between using
class
,struct
orunion
when defining a class, but here, talking about a declaration, no such distinction is made -- using oneclass-key
is equivalent to any other.从技术上讲,根据语言标准,代码是可以的。然而,由于至少一种最流行的编译器对此发出警告,因此它在实践中不起作用。
“从理论上讲,理论和实践没有区别。在实践中,是有区别的。”
Technically the code is ok, according to the language standard. However, as at least one of the most popular compilers issues a warning for this, it doesn't work in practice.
"In theory, there is no difference between theory and practice. In pratice, there is."
来自 警告 C4099:类型名称第一次使用“class”,现在使用“struct”(MS VS 2k8) 似乎至少有一些编译器根据所使用的关键字进行不同的处理,所以最好不要依赖它,即使技术上允许(其中我找不到确认参考)。
From Warning C4099: type name first seen using 'class' now seen using 'struct' (MS VS 2k8) it appears that at least some compilers mangle differently depending on keyword used, so best not to rely on it even if it's technically allowed (of which I can't find a confirming reference).
在 C++ 中,结构体就是类。具体来说:
这意味着您的类不是用
struct
定义的,它绝对不是一个结构体。因此,您使用 struct class-key 的前向声明是错误的。我不知道规范的任何部分允许前向声明使用明显错误的类键。我确信所讨论的宽松编译器会平等对待结构和类,并掩盖不正确的声明。在这种情况下,编译器可能不需要错误,但错误也不应该是意外的。In C++, a struct is a class. Specifically:
This implies that your class, which was not defined with
struct
, is definitely not a struct. Therefore, your forward declaration with the struct class-key is erroneous. I'm not aware of any part of the specification that allows a forward declaration to use a class-key that is clearly wrong. I'm sure that the lenient compilers in question treat structs and classes equally and are glossing over the incorrect declaration. An error may not be required from the compiler in this scenario, but neither should it be unexpected.我不知道这是否是根据 C 标准未定义的(或任何其他不严格符合的类别),但我确实知道,如果您有两个翻译单元不同意类型 ' foo' 被声明为“类”或“结构”,如下所示:
TU 1
TU 2
那么,至少某些编译器(特别是 MSVC++)会在每个翻译单元中以不同的方式修改
f
的名称,因此 TU 1 中f
的定义不满足 TU 2 中对f
的引用,并且您会收到链接错误。在现实生活中,当您有一个定义类A
的标头Ah
并需要引用类B
、C< 时,就会出现这种情况/code> 和
D
但它们的前向声明就足够了(因此,非常明智的是,不包括Bh
等)——你最好对那些实际定义所做的前向声明使用相同的关键字!I have no idea whether or not this is undefined (or any of the other categories of not-strictly-conforming) per the C standard, but I do know that if you have two translation units that don't agree on whether a type 'foo' is declared as a 'class' or a 'struct', like so:
TU 1
TU 2
then, at least some compilers (notably MSVC++) will mangle the name of
f
differently in each translation unit, so the definition off
in TU 1 does not satisfy the reference tof
in TU 2 and you get a link error. This comes up in real life when you have a headerA.h
that defines classA
and needs to refer to classesB
,C
, andD
but a forward declaration of them suffices (so it, quite sensibly, does not includeB.h
etc) -- you better use the same keyword for those forward declarations that the actual definitions do!MSVC10 抛出警告,警告页面指出将使用定义中给出的类型。
http://msdn.microsoft.com/en-us/library/695x5bes.aspx
MSVC10 throws a warning, and the warning page states that the type given in the definition will be used.
http://msdn.microsoft.com/en-us/library/695x5bes.aspx