目录
参考原文:https://blog.csdn.net/qq_17308321/article/details/79979514
前言
警告:不是错误的,但是有风险或表明可能有错误。
英文原文:http://gcc.gnu.org/onlinedocs/gcc-4.6.3/gcc/Warning-Options.html#Warning-Options
请求或取消警告选项
加上-Wall吧,gcc 默认不加参数的情况下 连定义了返回值的函数没有返回值都不报错。
-Wall,-Wextra 就是加-Wall 和-Wall不启动的选项也加上
(https://blog.csdn.net/qq_17308321/article/details/79979514)
-fsyntax-only
检查代码中的语法错误,但除此之外不要做任何事情。
-w (小写)
禁止所有警告消息。
-W (大写)
以“ -W ”请求特定的警告 - 可以隐式地请求隐式声明的警告。
-W和-Wall的区别
-Wall选项意思是编译后显示所有警告。
-W选项类似-Wall,会显示警告,但是只显示编译器认为会出现错误的警告。
在编译一些项目的时候可以-W和-Wall选项一起使用。
gcc -W -Wall test_w_wall testwwall.c
-Werror=
将指定的警告转换为错误。
请注意,指定-Werror = foo会自动隐含-W foo 。 但是, -Wno-error = foo并不意味着什么。
反过来:
-Wno-error取消编译选项-Werror
用途:
假设我们使用了一个人的代码A目录,里面有一个-Werror的选项,把所有的警告当做错误;又使用了另一个人的代码B目录,里面存在一堆Warning。这样,当我们把它们合在一起编译的时候,A中的-Werror选项会导致B的代码编译不过。但我们又不想去修改B的代码,怎么办?方法是,先add_subdirectory(A),之后,加上一句
set(CMAK_CXX_FLAGS "${CMAK_CXX_FLAGS} -Wno-error")
-Wno-这个前缀,就是用来取消一个编译选项的
然后,再add_subdirectory(B)
-Wfatal-errors
在发生第一个错误时中止编译。
请求和关闭告警方式
以“ -W ”请求特定的警告 - 可以隐式地请求隐式声明的警告。
以“ -Wno- ”开头关闭特定的警告;
$ gcc -Wall -Wno-unused test.c -o test
连带开启
某些选项(如-Wall和-Wextra )会打开其他选项,例如-Wunused ,这可能会启用其他选项,例如-Wunused-value 。
作用顺序和覆盖
具体的选项优先于不特定的选项,与命令行中的位置无关。
对于相同特征的选项,最后一个生效。
-Wall
(http://blog.sina.com.cn/s/blog_553230d70101efqv.html)
该选项相当于同时使用了下列所有的选项:
◆unused-function:遇到仅声明过但尚未定义的静态函数时发出警告。
◆unused-label:遇到声明过但不使用的标号的警告。
◆unused-parameter:从未用过的函数参数的警告。
◆unused-variable:在本地声明但从未用过的变量的警告。
◆unused-value:仅计算但从未用过的值得警告。
◆Format:检查对printf和scanf等函数的调用,确认各个参数类型和格式串中的一致。
◆implicit-int:警告没有规定类型的声明。
◆implicit-function-:在函数在未经声明就使用时给予警告。
◆char-subscripts:警告把char类型作为数组下标。这是常见错误,程序员经常忘记在某些机器上char有符号。
◆missing-braces:聚合初始化两边缺少大括号。
◆Parentheses:在某些情况下如果忽略了括号,编译器就发出警告。
◆return-type:如果函数定义了返回类型,而默认类型是int型,编译器就发出警告。同时警告那些不带返回值的 return语句,如果他们所属的函数并非void类型。
◆sequence-point:出现可疑的代码元素时,发出报警。
◆Switch:如果某条switch语句的参数属于枚举类型,但是没有对应的case语句使用枚举元素,编译器就发出警告(在switch语句中使用default分支能够防止这个警告)。超出枚举范围的case语句同样会导致这个警告。
◆strict-aliasing:对变量别名进行最严格的检查。
◆unknown-pragmas:使用了不允许的#pragma。
◆Uninitialized:在初始化之前就使用自动变量。
如$ gcc -Wall test.c -o test
也可以关闭其中某个告警:
如:$ gcc -Wall -Wno-unused test.c -o test
下面是使用-Wall选项的时候没有生效的一些警告项:
◆cast-align:一旦某个指针类型强制转换时,会导致目标所需的地址对齐边界扩展,编译器就发出警告。例如,某些机器上只能在2或4字节边界上访问整数,如果在这种机型上把char *强制转换成int *类型, 编译器就发出警告。
◆sign-compare:将有符号类型和无符号类型数据进行比较时发出警告。
◆missing-prototypes :如果没有预先声明函数原形就定义了全局函数,编译器就发出警告。即使函数定义自身提供了函数原形也会产生这个警告。这样做的目的是检查没有在头文件中声明的全局函数。
◆Packed:当结构体带有packed属性但实际并没有出现紧缩式给出警告。
◆Padded:如果结构体通过充填进行对齐则给出警告。
◆unreachable-code:如果发现从未执行的代码时给出警告。
◆Inline:如果某函数不能内嵌(inline),无论是声明为inline或者是指定了-finline-functions 选项,编译器都将发出警告。
◆disabled-optimization:当需要太长时间或过多资源而导致不能完成某项优化时给出警告。上面是使用-Wall选项时没有生效,但又比较常用的一些警告选项。
本文中要介绍的最后一个常用警告选项是-Werror。使用该选项后,GCC发现可疑之处时不会简单的发出警告就算完事,而是将警告作为一个错误而中断编译过程。该选项在希望得到高质量代码时非常有用。
-Wextra
这会启用一些未由-Wall启用的额外警告标志。 (此选项过去称为-W ,旧名称仍然受支持,但更新的名称更具描述性。)
-Wclobbered
-Wcast-function-type
-Wempty-body
-Wignored-qualifiers
-Wimplicit-fallthrough=3
-Wmissing-field-initializers
-Wmissing-parameter-type (C only)
-Wold-style-declaration (C only)
-Woverride-init
-Wsign-compare (C only)
-Wtype-limits
-Wuninitialized
-Wshift-negative-value (in C++03 and in C99 and newer)
-Wunused-parameter (only with -Wunused or -Wall)
-Wunused-but-set-parameter (only with -Wunused or -Wall)
选项-Wextra还会打印以下情况的警告消息:
指针与整数零与< , <= , >或>= 。
(仅限C ++)枚举器和非枚举器都出现在条件表达式中。
(仅限C ++)不明确的虚拟基础。
(仅限C ++)为已声明为register的数组下标。
(仅限C ++)取得已声明register的变量的地址。
(仅限C ++)基类不在派生类的复制构造函数中初始化。
==========================================================未整理==================================================
-Wchar-subscripts
警告如果数组下标有char类型。 这是错误的常见原因,因为程序员经常忘记这种类型是在某些机器上签名的。 此警告由-Wall启用。
-Wchkp
警告由指针界限检查器( -fcheck-pointer-bounds )发现的无效内存访问。
-Wno-coverage-mismatch
如果使用-fprofile-use选项时反馈配置文件不匹配,则警告 。 如果在使用-fprofile-gen编译和使用-fprofile-use编译时源文件发生更改,则具有配置文件反馈的文件可能无法与源文件匹配,并且GCC无法使用配置文件反馈信息。 默认情况下,此警告已启用并被视为错误。 -Wno-coverage-mismatch可用于禁用警告或-Wno-error = coverage-mismatch可用于禁用该错误。 禁用此警告的错误可能会导致代码质量不佳,并且仅在非常小的更改情况下才有用,例如修复现有代码库的错误。 不建议完全禁用该警告。
-Wno-cpp
(仅限于Objective-C,C ++,Objective-C ++和Fortran)
禁止#warning指令发出的警告消息。
-Wdouble-promotion (C, C++, Objective-C and Objective-C++ only)
当float类型的值隐式提升为double时发出警告。 具有32位“单精度”浮点单元的CPU实现float硬件,但在软件中模拟double精度。 在这样的机器上,由于软件仿真所需的开销,使用double值进行计算要昂贵得多。
使用double意外执行计算很容易,因为浮点文字隐含了double类型。 例如,在:
float area(float radius)
{
return 3.14159 * radius * radius;
}
编译器使用double执行整个计算,因为浮点文字是double 。
-Wduplicate-decl-specifier (C and Objective-C only)
警告如果声明有重复的const , volatile , restrict或_Atomic说明符。 此警告由-Wall启用。
-Wformat
-Wformat= n
检查对printf和scanf等的调用,以确保提供的参数的类型与指定的格式字符串相匹配,并且格式字符串中指定的转换有意义。 这包括标准函数,以及其他由printf , scanf , strftime和strfmon (X / Open扩展,而不是C标准)系列(或其他特定于目标系列)的格式属性(请参阅函数属性 )指定的标准函数。 哪些函数在没有指定格式属性的情况下被检查取决于所选择的标准版本,并且没有指定属性的函数的这些检查由-freestanding或-fno-builtin禁用。
格式将根据GNU libc版本2.2支持的格式特性进行检查。 这些包括所有ISO C90和C99功能,以及Single Unix Specification和一些BSD和GNU扩展的功能。 其他库实现可能不支持所有这些功能; GCC不支持关于超出特定图书馆限制的功能的警告。 但是,如果-Wpedantic与-Wformat 一起使用,则会提供有关格式特征的警告,但不包括在选定的标准版本中(但不包含strfmon格式,因为这些格式不在C标准的任何版本中)。 请参阅控制C语言的选项 。
-Wformat=1
-Wformat
选项-Wformat相当于-Wformat = 1 , -Wno-format相当于-Wformat = 0 。 由于-Wformat还检查几个函数的空格式参数, -Wformat也意味着-Wnonnull 。 这种格式检查级别的某些方面可以通过以下选项禁用: -Wno-format-contains-nul , -Wno-format-extra-args和-Wno-format-zero-length 。 -Wformat由-Wall启用。
-Wno-format-contains-nul
如果指定了-Wformat ,则不要警告有关包含NUL字节的格式字符串。
-Wno-format-extra-args
如果指定了-Wformat ,则不要警告有关printf或scanf格式函数的过多参数。 C标准指定了这样的参数被忽略。
如果未使用的参数位于用’ $ '操作数编号规范指定的已使用参数之间,通常仍会给出警告,因为实现无法知道传递给va_arg类型以跳过未使用的参数。 但是,在scanf格式的情况下,如果未使用的参数全部是指针,则此选项会抑制警告,因为Single Unix Specification指出允许使用这些未使用的参数。
-Wformat-overflow
-Wformat-overflow= level
警告对可能溢出目标缓冲区的格式化输入/输出函数(如sprintf和vsprintf 。 当由格式指令写入的确切字节数在编译时无法确定时,它将根据启发式进行估计,这取决于级别参数和优化。 虽然启用优化在大多数情况下会提高警告的准确性,但也可能导致误报。
-Wformat-overflow
-Wformat-overflow=1
-Wformat启用的-Wformat-overflow的第1级采用了一种保守的方法,只警告最有可能溢出缓冲区的调用。 在此级别,格式化具有未知值的指令的数字参数假定值为1,未知长度的字符串为空。 已知绑定到其类型的子范围的数字参数,或者其输出受其指令的精度或有限的字符串文字限制的字符串参数被假定为取值范围内的值,该范围导致输出中的大部分字节。 例如,下面对sprintf的调用被诊断出来,因为即使a和b都等于零,函数附加到目标缓冲区的终止NUL字符( ‘\0’ )也将被写入其末尾。 将缓冲区的大小增加一个字节足以避免警告,尽管它可能不足以避免溢出。
void f(int a,int b)
{
char buf [13];
sprintf(buf,“a =%i,b =%i \ n”,a,b);
}
-Wformat-overflow=2
级别2还会警告有关可能溢出目标缓冲区的调用,因为调用的参数长度或幅度足够大。 在级别2处 ,未知数值参数被假定为具有大于1的精度的带符号类型的最小可表示值,否则为最大可表示值。 未知的字符串参数的长度不能被假定为由指令的精度,或者它们可能评估的字符串文字的有限集合,或者它们可能指向的字符数组所限定,都假定为1个字符长。
在第2级,上述示例中的调用再次被诊断,但是这次因为使用等于32位的INT_MIN ,第一个%i指令将在目标缓冲区的末尾写入其一些数字。 为了保证呼叫安全,无论两个变量的值如何,目标缓冲区的大小必须增加到至少34个字节。 GCC在警告后的信息说明中包含缓冲区的最小大小。
增加目标缓冲区大小的替代方法是限制格式化值的范围。 字符串参数的最大长度可以通过指定格式指令中的精度来限制。 当格式指令的数值参数可以假定为小于它们类型的精度时,为格式说明符选择适当的长度修饰符将减少所需的缓冲区大小。 例如,如果上面示例中的a和b可以假定为处于short int类型的精度范围内,那么使用%hi格式指令或将参数强制转换为short可将缓冲区的最大所需大小减少到24个字节。
void f(int a,int b)
{
char buf [23];
sprintf(buf,“a =%hi,b =%i \ n”,a,(简写)b);
}
-Wno-format-zero-length
如果指定了-Wformat ,则不要警告有关零长度格式。 C标准规定允许零长度格式。
-Wformat=2
启用-Wformat加上其他格式检查。 目前相当于-Wformat -Wformat-nonliteral -Wformat-security-Wformat-y2k 。
-Wformat-nonliteral
如果指定了-Wformat ,则还会警告格式字符串是否不是字符串文字,因此无法检查,除非格式函数将其格式参数作为va_list 。
-Wformat-security
如果指定了-Wformat ,还会警告使用表示可能的安全问题的格式化函数。 目前,这会警告printf和scanf函数的调用,其中格式字符串不是字符串文字,也没有格式参数,如printf (foo); 。 如果格式字符串来自不可信输入且包含’ %n ',则这可能是安全漏洞。 (这是目前W-format-nonliteral提出的警告的一个子集,但将来警告可能会被添加到-Wformat-security中 ,而不包括在-Wformat-nonliteral中 。)
-Wformat-signedness
如果指定了-Wformat ,则还会警告格式字符串是否需要一个无符号参数并且该参数是否有符号,反之亦然。
-Wformat-truncation
-Wformat-truncation= level
警告关于调用可能导致输出截断的格式化输入/输出函数(如snprintf和vsnprintf警告。 当由格式指令写入的确切字节数在编译时无法确定时,它将根据启发式进行估计,这取决于级别参数和优化。 虽然启用优化在大多数情况下会提高警告的准确性,但也可能导致误报。 除非另有说明,该选项使用相同的逻辑 - 格式溢出 。
-Wformat-truncation
-Wformat-truncation=1
-Wformat启用的-Wformat-truncation的 Level 1采用了一种保守的方法,只警告对有界函数的调用,该函数的返回值未使用,并且很可能导致输出截断。
-Wformat-truncation=2
级别2还警告对使用返回值的有界函数的调用,并且在给定足够长度或幅度的参数时可能导致截断。
-Wformat-y2k
如果指定了-Wformat ,还会警告有关可能只产生两位数年份的strftime格式。
-Wnonnull
警告标记为非空值函数属性的参数需要传递空指针。
-Wnonnull包含在-Wall和-Wformat中 。 它可以通过-Wno-nonnull选项禁用。
-Wnonnull-compare
在比较标记nonnull空函数属性的参数与函数内的空值时发出警告。
-Wnonnull-compare包含在-Wall中 。 它可以通过-Wno-nonnull-compare选项禁用。
-Wnull-dereference
如果编译器检测到由于取消引用空指针而导致触发错误或未定义行为的路径,则发出警告。 该选项仅在-fdelete-null-pointer-checks处于活动状态时才有效,这是通过大多数目标中的优化启用的。 警告的精度取决于所使用的优化选项。
-Winit-self (C, C++, Objective-C and Objective-C++ only)
警告使用自己初始化的未初始化变量。 请注意,此选项只能与-Wuninitialized选项一起使用。
例如,只有在指定-Winit-self时,GCC才会在下面的代码片段中提醒i未初始化:
int f()
{
int i = i;
回报我;
}
此警告由C ++中的-Wall启用。
-Wimplicit-int (C and Objective-C only)
当声明没有指定类型时发出警告。 此警告由-Wall启用。
-Wimplicit-function-declaration (C and Objective-C only)
在声明之前使用函数时发出警告。 在C99模式下( -std = c99或-std = gnu99 ),默认情况下会启用此警告,并通过-pedantic-errors将其设置为错误 。 此警告也由-Wall启用。
-Wimplicit (C and Objective-C only)
与-Wimplicit-int和-Wimplicit-function-declaration相同 。 此警告由-Wall启用。
-Wimplicit-fallthrough
-Wimplicit- fallthrough与-Wimplicit- fallthrough = 3相同 , -Wno-implicit-fallthrough与-Wimplicit- fallthrough = 0相同 。
-Wimplicit-fallthrough= n
当开关盒跌落时发出警告。 例如:
switch (cond)
{
case 1:
a = 1;
break;
case 2:
a = 2;
case 3:
a = 3;
break;
}
当警告的最后一个语句不能通过时,例如当有一个返回语句或对noreturn属性声明的函数调用时,此警告不会警告。 -Wimplicit-fallthrough =也考虑到了控制流程语句,比如ifs,并且只在适当的时候发出警告。 例如
switch (cond)
{
case 1:
if (i > 3) {
bar (5);
break;
} else if (i < 1) {
bar (0);
} else
return;
default:
…
}
由于在某些情况下可能会出现切换情况,GCC提供了一个属性__attribute__ ((fallthrough)) ,该属性将与空语句一起使用来抑制通常会发生的警告:
switch (cond)
{
case 1:
bar (0);
__attribute__ ((fallthrough));
default:
…
}
C ++ 17提供了一种标准的方法来抑制使用[[fallthrough]];的-Wimplicit-Fallthrough警告[[fallthrough]]; 而不是GNU属性。 在C ++ 11或C ++ 14中,用户可以使用[[gnu::fallthrough]]; ,这是一个GNU扩展。 除了这些属性外,还可以添加一条跌落评论以使警告消失。 C或C ++样式注释的整个