不常见但有用的GCC命令行选项 - 第2部分

gcc编译器提供了一个看似永无止尽的命令行选项列表。 当然,没有任何机构使用或具有所有的专业知识,但每个gcc用户都应该选择一些选择,如果不是必须的话。 虽然其中一些是常用的,但其他一些是有点不常见,但同样有用。

在本文系列中,我们将重点介绍一些不常见但有用的gcc命令行选项,并已在第1部分中介绍了其中的几个。

如果您记得,在本教程系列的第一部分的开头,我简要提到开发人员通常用于生成警告的“选项”不包含某些特定的警告。 如果您不知道这些警告,并且不了解如何启用它们,请不要担心,因为我们将在本文中详细解释所有这些。

除此之外,我们还将覆盖与浮点变量相关的gcc警告选项,以及如果列表增大,则如何更好地管理gcc命令行选项。

但是,在我们向前推进之前,请记住,本教程中提到的所有示例,命令和说明都已在Ubuntu 16.04 LTS上进行了测试,而我们使用的gcc版本为5.4.0。

启用不被-Wall覆盖的警告

虽然gcc编译器的-Wall选项涵盖了大多数警告标志,但仍有一些保持禁用。 要启用它们,请使用-Wextra选项。

例如,看看下面的代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
int i=0;
/* ...
some code here
...
*/

if(i);
return 1;
return 0;
}

在“if”的情况下,我不小心放了一个分号。 现在,当使用以下gcc命令编译代码时,不会产生警告。

gcc -Wall test.c -o test

但是当使用-Wextra选项时:

gcc -Wall -Wextra test.c -o test

发出警告:

test.c: In function ‘main’:
test.c:10:8: warning: suggest braces around empty body in an ‘if’ statement [-Wempty-body]
if(i);

从上述警告中可以清楚的看出, -Wextra选项在内部启用了-Wempty-body标志,该标志在检测到可疑代码时发出警告。 以下是此选项启用的警告标志的完整列表:

-Wclobbered,-Wantpty-body,-Wignition-qualifiers,-Wmissing-field-initializers,-Wmissing-parameter-type(仅限C),-Wold-style-declaration(仅限C),-Woverride-init,-Wsign-比较,-Wtype-limits,-Wuninitialized,-Wunused-parameter(仅与-Wunused或-Wall)和-Wunused-but-set-parameter(仅与-Wunused或-Wall)。

如果您想了解上述标记的内容,请访问gcc的手册页

继续,在以下情况下,-Wextra选项还会发出警告:

  • 将指针与整数零与<,<=,>或> =进行比较
  • (仅C ++)枚举器和非枚举器都出现在
    条件表达式。
  • (仅限C ++)模糊虚拟基础。
  • (仅限C ++)下标已声明的数组
    寄存器。
  • (仅C ++)取一个变量的地址
    宣布登记
  • (仅C ++)基类没有在派生类中初始化
    复制构造函数。

在权衡比较中启用浮点值的警告

您可能已经知道,不应该测试浮点值的确切平等(不知道这一点 - 在这里阅读浮点比较相关的常见问题)。 但是,即使您不小心这样做,gcc编译器是否抛出任何警告或错误? 我们来看看:

这是一个使用==运算符比较浮点变量的代码

#include<stdio.h>

void compare(float x, float y)
{
if(x == y)
{
printf("\n EQUAL \n");
}
}


int main(void)
{
compare(1.234, 1.56789);

return 0;
}

这里是gcc命令(包含-Wall和-Wextra选项),用于编译此代码:

gcc -Wall -Wextra test.c -o test

不幸的是,上述命令不会产生任何与浮点比较相关的警告。 快速浏览GCC的手册页显示,存在一个专用选项-Wfloat-equal ,应该在这些情况下使用。

这是包含此选项的命令:

gcc -Wall -Wextra -Wfloat-equal test.c -o test

以下是它产生的输出:

test.c: In function ‘compare’:
test.c:5:10: warning: comparing floating point with == or != is unsafe [-Wfloat-equal]
if(x == y)

因此,您可以在上面的输出中看到,-Wfloat-equal选项强制gcc产生与浮动比较相关的警告。

这是gcc手册页面关于这个选项的说明:

The idea behind this is that sometimes it is convenient (for the programmer) to consider floating-point values as approximations to infinitely precise real numbers. If you are doing this, then you
need to compute (by analyzing the code, or in some other way) the maximum or likely maximum error that the computation introduces, and allow for it when performing comparisons (and when producing
output, but that's a different problem). In particular, instead of testing for equality, you shouldcheck to see whether the two values have ranges that overlap; and this is done with the relational operators, so equality comparisons are probably mistaken.

如何更好地管理gcc命令行选项

如果您在gcc命令中使用的命令行选项列表变大而难以管理,那么可以将其放在文本文件中,并将该文件的名称作为参数传递给gcc命令。 为此,您必须使用@file命令行选项。

例如,如果以下是您的gcc命令:

gcc -Wall -Wextra -Wfloat-equal test.c -o test

然后,您可以将三个警告相关选项放在名为“gcc-options”的文件中:

$ cat gcc-options 
-Wall -Wextra -Wfloat-equal

而您的gcc命令变得不那么混乱,易于管理:

gcc @gcc-options test.c -o test

以下是gcc手册页面关于@file的内容:

Read command-line options from file. The options read are inserted in place of the original @file option. If file does not exist, or cannot be read, then the option will be treated literally, and not removed.

Options in file are separated by whitespace. A whitespace character may be included in an option by surrounding the entire option in either single or double quotes. Any character (including a backslash) may be included by prefixing the character to be included with a backslash. The file may itself contain additional @file options; any such options will be processed recursively.

结论

所以我们在本教程系列中总共介绍了5个不常见但有用的gcc命令行选项:-save-temps,-g,-Wextra,-Wfloat-equal和@file。 花时间练习每个人,不要忘记了解gcc手册页面提供的所有细节。

您是否知道或使用其他这样有用的gcc命令行选项,并希望与世界分享? 将所有细节留下以下评论。

赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏