2009-01-22 4 views

回答

23

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

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

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

+0

伟大的建议,谢谢。 – 2009-01-22 10:59:18

+2

MS Mangling Scheme http://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B_Name_Mangling#Data_Type:`union`编码为`T`,`struct`为`U`和`class`为`V` 。 – 2011-02-01 19:46:15

1

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

+1

在使用不同名称修改算法的编译器上可能会有问题。 – MSalters 2009-01-22 13:27:15

0

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

4

只是将MSalters的评论反对this帖子发表到最高层。在使用名称中的'class'或'struct'关键字时,我有几个很难找到链接器错误。

如果你不指望它是一个问题,你可以留下几个小时头!

1

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

2

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

1

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

相关问题