18

这个警告有什么可担心的吗?我读过它会导致不稳定的行为?

这是我正在尝试编译的示例,有人可以向我解释为什么作者将对象声明为类,然后将 typedef 定义为结构吗?如果班级是POD这样做是完全正常的吗?

谢谢。

4

7 回答 7

27

当您有一个与另一个相矛盾的类型声明(一个说“类”,另一个说“结构”)时,会出现此警告。给定一个定义规则,除了至多一个之外的所有声明都必须是前向声明。警告通常表明一个类型的前向声明是错误的,通常是一个简单的错字,应该修复。在这种情况下应该没有副作用,但你真的应该修复它。

但是,如果您有类型名称冲突(可能是由使用“使用命名空间”子句或全局命名空间污染引起的),可能会发生一些非常讨厌的事情。这些警告可能表明您正在混合来自两个不同库的标头并且类型名称有冲突。在这些条件下编译的代码可能会做一些非常意想不到的事情。

我的建议 - 了解警告出现的原因并修复它。如果警告出现在第三方产品中,请坚持让他们修复它。

于 2009-01-22T09:52:56.380 回答
5

只是为了将 MSalters 对上面这篇文章的评论带到顶层。由于 VC 在其名称的重整中使用“类”或“结构”关键字,我遇到了几个很难找到的链接器错误。

如果您不认为这是一个问题,您可能会摸不着头脑好几个小时!

于 2009-01-22T18:27:31.270 回答
3

我在我的博客文章“ C4099 真的是一个愚蠢的警告吗?”中深入讨论了这个警告。. 我的结论是最好关闭它。:-) 好吧,至少对我来说。

于 2010-06-22T20:59:53.797 回答
2

Richard Corden 是正确的 - MS 有这个警告是有原因的。对于 MS 编译器,修饰(损坏)名称包括哪个类键structclass) 用于声明类型。如果当错误的类键可见时,某个将某个对象作为参数或返回该对象的函数在某处被引用,您将不会收到编译器错误,但链接器会抱怨,因为修饰名称不同。链接器错误只显示它正在寻找的符号,并且很容易忽略那里的类键不匹配,因此更早、更详细的编译器警告很有价值。当然,这两个版本仍然有可能不会出现在同一个编译单元中,如果您认为唯一的区别是默认成员可见性,您可能会摸不着头脑。

mangling 的区别与 C++ 标准相冲突,C++ 标准说前向声明类似于struct Foo;class Foo;是等价的,因此应该使用相同的 mangling。

于 2009-04-29T13:43:53.690 回答
1

虽然这被认为是不好的做法,但我认为混合类定义和结构声明应该没有问题,因为它们基本上是相同的数据类型。主要区别在于结构成员默认是公共的,与私有的类成员相反,但内存布局是相同的。

于 2009-01-22T09:47:20.913 回答
1

在 C++ 中,类和结构的唯一区别是类的成员变量、成员函数和基类默认是私有的,而在结构中它们默认是公有的;所以,类是 POD 的事实在这里不应该有任何区别。
我猜这个警告来自代码维护(定义在某处更新但没有在其他地方更新),并修复代码以使警告消失(例如在 typedef 中使用类)。

于 2009-01-22T09:48:08.277 回答
1

我看到可能导致此警告的一件事是尝试从 DLL 中 #import .tlb 文件,同时在项目中使用相同的 DLL 作为引用。我刚刚通过从我的项目中删除 DLL 作为引用来解决这个问题。

于 2014-06-25T03:17:15.363 回答