与Linux上的gcc不同,英特尔编译器没有很好的警告预设。主要的警告选项是-wn
,其中n可以是0到5的数字。默认值为1,而4和5在Linux上没有意义。它还支持一些类似于-Wall
和-Wextra
的gcc选项。然而:
-Wall
与gcc相比非常简约,正如您所发现的
-w2
和-w3
启用了一些有用的诊断信息,但也会产生大量垃圾邮件
-diag-disable:remark
可以去除那些垃圾邮件,但也会去除许多有用的诊断信息
最终,-w3 -diag-disable:remark
是英特尔编译器拥有的最佳预设,但它仍然比gcc -Wall
更加简约。您需要从一个最小化的警告集开始并建立自己的警告集,或者从最大化的诊断开始,并使用-wd
禁用任何让您感到烦恼的警告。
建立
第一种方法的主要缺点是,英特尔实际上没有记录大多数警告信息,因此很难知道可以启用哪些警告。但是,它支持许多GCC命令行标志,因此GCC文档是一个好的起点。例如,以下设置与g++ -Wall
相当接近,这对于您想要在其中一个上开发并有机会使用另一个进行干净的构建非常方便:
icpc -Wall -Warray-bounds -Wchar-subscripts -Wcomment -Wenum-compare -Wformat -Wuninitialized -Wmaybe-uninitialized -Wmain -Wnarrowing -Wnonnull -Wparentheses -Wpointer-sign -Wreorder -Wreturn-type -Wsign-compare -Wsequence-point -Wtrigraphs -Wunused-function -Wunused-but-set-variable -Wunused-variable -Wwrite-strings
这不是与gcc -Wall
完全匹配的内容。GCC和ICC在上述警告的实现上有所不同。我还无法找到与这些GCC警告相匹配的ICC选项:
-Wformat-contains-nul
-Wunused-label
-Wstrict-overflow
-Wvolatile-register-var
我故意将它们省略掉,因为ICC版本比GCC更加垃圾邮件式的。
-Wstrict-aliasing So broad that any use of polymophism will cause this warning
-Wswitch Requires a default even if you have cases for all enumeration values
简化
如果不考虑GCC的兼容性问题,学习ICC的警告最简单的方法就是启用所有警告,然后决定是否喜欢这些警告。如果不喜欢某个警告,可以使用其诊断号将其禁用,这通常比GCC的选项更具有细粒度。
icpc -w3 -wd1418,2259
以下是一些我曾经看到被禁用的诊断信息:
- 383:值被复制到临时变量中,对临时变量进行了引用
- 869:参数“*”从未被引用过
- 981:操作数的计算顺序未指定
- 1418:外部函数定义没有先前声明
- 1572:浮点数等式和不等式比较不可靠
- 2259:非指针转换可能丢失有效位
- 11074:内联限制被最大尺寸(或最大总大小)所阻止
- 11076:要获得完整报告,请使用-qopt-report=4 -qopt-report-phase ipo
- 161:为无法识别的编译指令禁用警告
但我建议您将所有诊断都打开,然后逐渐删除对您的代码库有问题的那些。