警告C4099:使用'struct'时首次看到使用'class'的类型名称(MS VS 2k8)

问题描述 投票:15回答:7

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

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

谢谢。

c++ compiler-warnings
7个回答
25
投票

如果您有一个与另一个相矛盾的类型声明(一个表示“class”,另一个表示“struct”),则会出现此警告。给定一个定义规则,除最多一个之外的所有声明必须是前向声明。警告通常表明类型的前向声明是错误的,通常是一个简单的拼写错误,应该修复。在这种情况下,应该没有副作用,但你真的应该解决它。

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

我的建议 - 理解为什么警告出现并修复它。如果警告是在第三方产品中,请坚持要求他们修复它。


5
投票

只是为了将MSalters对this帖子的评论带到最高水平。我有几个很难找到链接器错误,因为VC在其名称的重整中使用了'class'或'struct'关键字。

如果你不认为这是一个问题,你可能会留下几个小时的头!


3
投票

我在博客文章“Is C4099 really a sillywarning?"中深入讨论了这个警告。我的结论是它最好关闭。:-)嗯,至少对我而言。


2
投票

理查德科登是正确的 - 有一个原因,MS有这个警告。对于MS编译器,修饰(修改)名称包括用于声明类型的类 - 键(structclass)。如果某个对象作为参数或返回该对象的函数在错误的类键可见时被引用,则不会出现编译器错误,但链接器会抱怨,因为修饰的名称不同。链接器错误仅显示它正在寻找的符号,并且很容易忽略那里的类密钥不匹配,因此更早,更详细的编译器警告是有价值的。当然,这两个版本仍然可能不会出现在同一个编译单元中,如果您认为唯一的区别是默认成员可见性,您可能会有一段时间不知所措。

修改的差异与C ++标准冲突,后者表示像struct Foo;class Foo;这样的前向声明是等价的,所以应该使用相同的修改。


1
投票

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


1
投票

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


0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.