3.5 其他警告选项

GCC提供很多不包含在'-Wall'中的其他警告选项,他们也非常有用。特别是当源代码在技术上是有效的但是非常可能产生问题时产生警告。这些选项的依据是日常使用中根据经验总结的通用错误--他们没有包含在'-Wall'选项中是因为他们仅仅识别可能不确定的或者可疑的代码。

因为这些警告可以使用在有效代码上,没有必要始终使用这些选项编译程序。它们更适合周期性的使用和审查结果,检查任何异常或者在一些程序和文件中使用。

'-W'

这是一个通用的选项类似于'-Wall'选项,用于检查可选的常用编程错误,例如没有返回值的函数和有符号与无符号值之间的比较。下面的示例程序测试一个无符号整型值是否为负(当然这是不可能的):

int

foo (unsigned int x)

{

if (x < 0)

return 0; / cannot occur /

else

return 1;

}

使用'-Wall'选项编译此程序不会产生警告,

$ gcc -Wall -c w.c

但是当使用'-W'选项时:

$ gcc -W -c w.c

w.c: In function ‘foo’:

w.c:4: warning: comparison of unsigned

expression < 0 is always false

通常'-W'和'-Wall'选项一起使用。

'-Wconversion'

这个选项检查会造成异常结果的类型冲突错误。例如给一个无符号变量赋一个负值,就像下面的代码,

unsigned int x = -1;

ANSI/ISO C标准在技术上是允许这种情况的(这个负值会被转为正值)但是会产生一个简单的程序错误。如果你需要使用这种转换,你可以明确声明例如((unsigned int) -1),来避免产生警告信息。在计算机中这种情况的结果是机器所能表示的一个无符号整数的最大值。

'-Wshadow'

这个选项检查在一个范围内重复定义的变量名。这种情况被称为影子变量,这会和先前出现的变量产生混淆。

下面的函数声明了一个本地变量y,它掩盖了函数体内的声明:

double

test (double x)

{

double y = 1.0;

{

double y;

y = x;

}

return y;

}

在ANSI/ISO C标准中这是有效的,它的返回值是1。当看到y=x时,影子变量y可能使返回值看起来像是x(特别是在一个复杂和巨大的函数中)。

这种情况也会出现在函数名上。例如下面的程序试图定义一个sin变量,它掩盖了标准库函数sin(x)。

double

sin_series (double x)

{

/ series expansion for small x /

double sin = x (1.0 - x x / 6.0);

return sin;

}

这个错误可以使用'-Wshadow'选项检查出来。

'-Wcast-qual'

这个选项检查指针使用时丢失了指针限定符,如const。下面的函数丢失了输入参数的限定符const,导致指针可以被改变:

void

f (const char * str)

{

char s = (char )str;

s[0] = ’\0’;

}

对str指向的原始内容进行修改违反了const属性。这个选项会发出警告丢失了str变量的限定符。

‘-Wwrite-string’

这个选项隐含的将所有程序中定义的字符串常量加上const限定符,当试图改写这些字符串常量时会导致编译时发出警告。修改字符串常量会导致什么结果ANSI/ISO标准没有做出定义,GCC反对这种行为。

‘-Wtraditional’

这个选项检查当代码片段在ANSI/ISO标准的编译器和“传统”早期ANSI编译器之间解释不一样时发出警告。当维护老旧的软件时非常有必要使用这个选项来检查那些代码和ANSI/ISO标准不同。

上面的选项会产生诊断信息但是允许编译器继续编译并生产目标文件或者可执行文件。对于大型程序而言当警告产生的时候就立即停止编译是非常有用的。’-Werror’选项会改变编译器默认行为将警告直接变成错误,从而使警告出现时停止编译。