MSVC -Wall中标准标头中的数千条警告是怎么回事?


67

有人似乎建议您使用-Wall,但是当我在一个只有main.cpp并包含一些包含项的小型测试项目上进行操作时,我在标准标头或Windows标头中收到5800条警告。

那是预期的行为吗?我该如何免费发布编译警告?

以下是一些阅读乐趣:

1>c:\program files\microsoft visual studio 10.0\vc\include\stdint.h(105): warning C4668: '_INTPTR' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(109): warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data member '_wfinddata64i32_t::attrib'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(114): warning C4820: '_wfinddata64i32_t' : '4' bytes padding added after data member '_wfinddata64i32_t::name'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(118): warning C4820: '_wfinddata64_t' : '4' bytes padding added after data member '_wfinddata64_t::attrib'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(488): warning C4820: '_stat32' : '2' bytes padding added after data member '_stat32::st_gid'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(504): warning C4820: 'stat' : '2' bytes padding added after data member 'stat::st_gid'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(520): warning C4820: '_stat32i64' : '2' bytes padding added after data member '_stat32i64::st_gid'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(521): warning C4820: '_stat32i64' : '4' bytes padding added after data member '_stat32i64::st_rdev'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(525): warning C4820: '_stat32i64' : '4' bytes padding added after data member '_stat32i64::st_ctime'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(534): warning C4820: '_stat64i32' : '2' bytes padding added after data member '_stat64i32::st_gid'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(548): warning C4820: '_stat64' : '2' bytes padding added after data member '_stat64::st_gid'
1>c:\program files\microsoft visual studio 10.0\vc\include\wchar.h(549): warning C4820: '_stat64' : '4' bytes padding added after data member '_stat64::st_rdev'
1>c:\program files\microsoft visual studio 10.0\vc\include\crtdbg.h(1078): warning C4986: 'operator new[]': exception specification does not match previous declaration
1>          c:\program files\microsoft visual studio 10.0\vc\include\new(79) : see declaration of 'operator new[]'
1>c:\program files\microsoft visual studio 10.0\vc\include\crtdbg.h(1095): warning C4986: 'operator delete[]': exception specification does not match previous declaration
1>          c:\program files\microsoft visual studio 10.0\vc\include\new(77) : see declaration of 'operator delete[]'
1>c:\program files\microsoft visual studio 10.0\vc\include\typeinfo(76): warning C4820: 'type_info' : '3' bytes padding added after data member 'type_info::_M_d_name'
1>c:\program files\microsoft sdks\windows\v7.0a\include\basetsd.h(114): warning C4668: '__midl' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(8154): warning C4820: '_SECURITY_QUALITY_OF_SERVICE' : '2' bytes padding added after data member '_SECURITY_QUALITY_OF_SERVICE::EffectiveOnly'
1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(8165): warning C4820: '_SE_IMPERSONATION_STATE' : '2' bytes padding added after data member '_SE_IMPERSONATION_STATE::EffectiveOnly'
1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(8334): warning C4820: '_QUOTA_LIMITS' : '4' bytes padding added after data member '_QUOTA_LIMITS::PagefileLimit'
1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(8357): warning C4820: '_QUOTA_LIMITS_EX' : '4' bytes padding added after data member '_QUOTA_LIMITS_EX::PagefileLimit'
1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(8405): warning C4820: '_JOBOBJECT_BASIC_LIMIT_INFORMATION' : '4' bytes padding added after data member '_JOBOBJECT_BASIC_LIMIT_INFORMATION::SchedulingClass'
1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(8984): warning C4820: '_FILE_NOTIFY_INFORMATION' : '2' bytes padding added after data member '_FILE_NOTIFY_INFORMATION::FileName'
1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(9012): warning C4820: '_REPARSE_GUID_DATA_BUFFER' : '3' bytes padding added after data member '_REPARSE_GUID_DATA_BUFFER::GenericReparseBuffer'
1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(10131): warning C4820: '<unnamed-tag>' : '3' bytes padding added after data member '<unnamed-tag>::Data'
1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(10241): warning C4820: '<unnamed-tag>' : '4' bytes padding added after data member '<unnamed-tag>::DecreaseTime'
1>c:\program files\microsoft sdks\windows\v7.0a\include\winnt.h(10262): warning C4820: '<unnamed-tag>' : '4' bytes padding added after data member '<unnamed-tag>::TimerInterval' 
1>c:\program files\microsoft sdks\windows\v7.0a\include\wincrypt.h(1440): warning C4668: 'NTDDI_WINLH' is not defined as a preprocessor macro, replacing with '0' for '#if/

原因是默认情况下禁用了这些警告。不要使用-Wall
Benjamin Lindley

1
GCC有一种抑制来自系统和库标题(-isystem而不是-I#pragma GCC system_header)的警告的方法。VC是否一样,还是/Wall禁用它?
greyfade 2010年


Answers:


44

Visual C ++/Wall启用默认情况下禁用的所有警告/W4。如您所知,有很多理由默认情况下会禁用许多警告(感谢编译器,因为它告诉我您已添加了填充;我非常感谢!)。最好只/W4在Visual C ++上使用。

英特尔C ++也是如此(我不了解其他利用EDG前端的编译器)。如果将其设置为/W5,则会发出大量信息性消息。我个人最喜欢的是,如果存储类说明符不在声明的开头,它会警告您(因此,const static int不可以,但是static const int可以)。


32
实际上,这很令人沮丧,因为VS库不允许使用-Wall。发出所有警告也有很好的理由。标准头文件正在生成这样的警告,这简直是糟糕的编码-或编译器发出了无意义的警告(VS有几种警告)。
edA-qa mort-ora-y

8
@edA:我不知道是什么让用户感到沮丧,以至于使用/Wall警告会引起很多警告:正如我在回答中所解释的那样,/Wall启用了许多警告,尽管有时可能有用,但在大多数情况下却没有用。 /WallVisual C ++中的含义与-Wallg ++中的含义不同(确实,g ++“/Wall错了”,因为它实际上并未启用所有警告)。无论如何,在Visual C ++中,所有常用且重要的有用警告均由启用/W4
James McNellis 2011年

41
如果您不能使用标准库编译程序并且没有收到警告,则几乎会使该选项无用。您将无法在代码中对库警告和警告进行排序。我只对代码中的内容感兴趣,而不对标准库感兴趣。
edA-qa mort-ora-y

1
@ edA-qamort-ora-y问题是实际上很多“警告”应该是注释。例如,C4820(“警告:我添加了填充。”)或C4514(“警告:我优化了从未调用的内联函数”。)。有些是有用的,但并不是真正可以更改的内容(例如C4710(“警告:inline函数实际上未内联。”)std::swprintf()因为它具有可变的参数列表)。
贾斯汀时间-恢复莫妮卡

有些确实有用,但仍应注意。例如,C4514(再次)是未引用的函数类似std::bad_alloc::bad_alloc;您可以查看C4514警告,以获取除其他事项外不会引发的快速异常列表。
贾斯汀时间-恢复莫妮卡

27

要从无法控制的系统头中禁用警告,只需使用以下结构:

#pragma warning(push, 0)       
//Some includes with unfixable warnings
#pragma warning(pop)

或更针对特定的警告:

#pragma warning( push )
#pragma warning( disable : 4081)
#pragma warning( disable : 4706 )
// system header includes 
#pragma warning( pop )

这个答案是从另一个Stack Overflow线程提出的:(/programming/2541984/how-to-suppress-warnings-in-external-headers-in-visual-c)。

我完全同意“ edA-qa mort-ora-y”的评论。我想查看代码中的所有警告,包括C4265之类的重要内容(DTOR不是虚拟的)。尽管C4265处于警告级别3,但是Microsoft明智地默认将其关闭,并且您需要/ Wall来获取它。有关隐藏哪些警告的更多信息,请参见此页面:

http://msdn.microsoft.com/zh-CN/library/23k5d385(v=vs.80).aspx

为了看到这些并抑制来自外部标头的噪音,此页面提供了很好的建议,我认为可以完全回答启动此线程的原始问题:

http://blogs.msdn.com/b/vcblog/archive/2010/12/14/off-by-default-compiler-warnings-in-visual-c.aspx

基本上,它建议使用适当的#pragmas创建一个'global'包含文件,以抑制您不关心的警告(可能是C4820填充的警告),以上述方式防范外部标头,然后使用/进行编译壁。这是一项工作,但值得。在GCC下,使用-isystem只是一个问题。微软开发:注意!VS是一种智能产品,但有时使用简单的东西却真的很愚蠢。


1
您不必使用/Wall。您可以使用启用特定的功能/w34265。另一方面,您可以使用/Wall,然后再禁用诸如填充警告之类的特定内容/wd4820。我同意这-isystem将是一个有用的功能。
cremno

9

我知道这已经晚了,但是我相信我可以使用/ Wall来存储自己的文件,但是不必看到Microsoft或其他“外部”标头发出的噪音。假设您正在通过stdafx.h使用预编译的头文件。

  1. 对于项目,将警告级别设置为/ Wall(最大警告)
  2. 对于文件stdafx.cpp,将警告级别设置为/ W4(启用了许多警告,但MS标头静默通过)
  3. 对于项目,在“禁用特定警告”下,添加4652

前两个似乎很明显。但是,当stdafx.h包含在您自己的文件中时,警告级别不匹配,并发出警告C4652。这打败了整个练习。但是现在,这个消息也被抑制了。

为每个新项目执行此操作有点繁琐,但不如许多单独的#pragma warning()抑制操作那么糟糕。



2

在MSVC 2010中

选件

配置属性

C / C ++

高级

禁用特定警告

设置一个值,例如4820; 4996; 4514; 4710, 以明确禁用您认为不重要的警告。此时,您可以-WALL无需担心


公平地说,C4514有时可能非常有用,但这并不是大多数时候。例如,“ C4514:std::bad_alloc::bad_alloc优化输出”(措辞)非常好(保证不会bad_alloc抛出异常),但是类似“ C4514:'std :: _ Maklocbyte'优化输出”或“ C4514:'std :: to_wstring “最优化”(释义)通常会少一些。
贾斯汀时间-恢复莫妮卡

1

使用VC6和Microsoft Platform SDK编译各种软件堆栈时(例如在BaseTsd.h中),我遇到相同的初始问题。

我(我们)要做的是控制代码的编译器警告级别-我们希望能够使用/ W标志。实际上,正如已经指出的,/ W4启用所有通常有用的警告(以及一些虚假的...)。

由于问题来自MSFT头文件,因此我以干净的方式修改了Microsoft提供的头文件。实施的变化不多。

如果编译器抱怨C4305警告,请在源文件中插入:

#pragma warning( disable : 4305)

在违规行之前,然后:

#pragma warning( default : 4305)

在违规行之后。无副作用。微软可能会这样做。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.