2.2 查找简单程序中的错误

正如上面提到的,当编写C和C++程序时编译器警告是非常有效的检查错误的方法。为了证明这种说法下面的程序有一个微妙的错误:printf函数的使用有错误,为一个整型值指定了一个浮点格式'%f'的格式化字符串:

include

int

main (void)

{

printf ("Two plus two is %f\n", 4);

return 0;

}

一眼看去这个错误并不明显但是如果使用了'-Wall'警告选项,编译器可以检查出来这个错误。

使用'-Wall'选项编译上面的程序'bad.c'会产生下面的信息:

$ gcc -Wall bad.c -o bad

bad.c: In function ‘main’:

bad.c:6: warning: double format, different

type arg (arg 2)

它指出'bad.c'文件中的第6行的格式化字符串使用不正确。GCC输出的信息总是以这样的格式显示“文件:行号:信息”。编译器会辨别阻止成功编译的错误信息和包含潜在问题的警告信息(但是不会停止编译程序)。

在这个例子中,正确的格式应该是'%d'(printf允许指定的格式可以再任何C语言书中找到,例如《GNU C Library Reference Manual》)。

如果没有'-Wall'选项,程序的编译会没有任何警告信息但是程序的运行会输出错误的结果:

$ gcc bad.c -o bad

$ ./bad

Two plus two is 2.585495 (错误输出)

指定错误的格式导致了错误的输出是因为printf函数传递了一个整型数而不是一个浮点数。整型数和浮点数在内存中以不同的格式存放并且一般占用不同的字节数,加载了一个错误的结果。实际输出的结果依赖于不同的平台和环境而不同。

很明显没有检查编译器警告的程序是非常危险的。如果任何一个函数使用错误会导致整个程序崩溃挥着产生错误的结果。打开编译器警告选项'-Wall'会检测到很多C程序中的常见错误。