The 海湾合作委员会手册没有说明
任何互斥的最后一个-std=...
指定的选项生效。第一次出现
或最后一次出现是唯一的选择。有无数
从有限集中获取互斥替代值的 GCC 标志 - 相互
互斥,至少对翻译单元的语言取模。让我们称呼他们为互斥选项简而言之。
最后设置生效的记录似乎是随机的。这是
记录为-O
正如您所指出的,一般而言,对于相互排斥的警告选项,也许
其他的。从来没有记录表明first多个设置生效,因为
这从来都不是真的。
该文档以历史惯例为基础,但一致性并不完美
类 UNIX 操作系统中的命令使用情况。如果命令接受互斥选项
那么最后一次出现的选项生效。如果命令是——不寻常——
仅在该选项第一次出现时执行操作,那么这将是一个错误
接受后续事件的命令:它应该给出使用错误。
这是习惯和做法。该定制有助于使用以下工具编写脚本:
尊重它,例如脚本可以调用传递某些默认设置的工具
互斥选项,但允许用户通过脚本的参数覆盖该设置,
其值可以简单地附加到默认调用中。
如果没有达到您想要的效果的官方 GCC 文档,您可能会得到
通过尝试查找任何不适合的 GCC 互斥选项来保证
最后发生的情况生效。这是一刺:
我将编译并链接该程序:
main.cpp
#include <cstdio>
#if __cplusplus >= 201103L
static const char * str = "C++11";
#else
static const char * str = "Not C++11";
#endif
int main()
{
printf("%s\n%d\n",str,str); // Format `%d` for `str` mismatch
return 0;
}
使用命令行:
g++ -std=c++98 -std=c++11 -m32 -m64 -O0 -O1 -g3 -g0 \
-Wformat -Wno-format -o wrong -o right main.cpp
它要求矛盾的选项对:
-
-std=c++98 -std=c++11
:符合C++98。符合C++11。
-
-m32 -m64
:生成 32 位代码。生成 64 位代码。
-
-O0 -O1
: 根本不优化。优化至级别 1。
-
-g3 -g0
:发出最大调试信息。不发出调试信息。
-
-Wformat -Wno-format
。完整性检查printf
论据。不要对它们进行理智检查。
-
-o wrong -o right
。输出程序wrong
。输出程序right
它无需诊断即可成功构建:
$ echo "[$(g++ -std=c++98 -std=c++11 -m32 -m64 -O0 -O1 -g3 -g0 \
-Wformat -Wno-format -o wrong -o right main.cpp 2>&1)]"
[]
不输出任何程序wrong
:
$ ./wrong
bash: ./wrong: No such file or directory
它确实输出一个程序right
:
$ ./right
C++11
-1713064076
这告诉我们它被编译为C++11
, not C++98
.
垃圾暴露的bug-1713064076
没有确诊是因为-Wno-format
, not -Wformat
,生效了。
它是 64 位而非 32 位可执行文件:
$ file right
right: ELF 64-bit LSB shared object, x86-64 ...
已经优化了-O1
, not -O0
, 因为:
$ "[$(nm -C right | grep str)]"
[]
显示本地符号str
不在符号表中。
并且它不包含调试信息:
echo "[$(readelf --debug-dump right)]"
[]
as per -g0
, not -g3
.
由于GCC是开源软件,解决疑虑的另一种方式
至少关于 C 程序员可以使用的行为,
是检查相关的源代码,可通过git
源代码控制在https://github.com/gcc-mirror/gcc.
您的问题的相关源代码已在文件中gcc/gcc/c-family/c-opts.c,
功能,
/* Handle switch SCODE with argument ARG. VALUE is true, unless no-
form of an -f or -W option was given. Returns false if the switch was
invalid, true if valid. Use HANDLERS in recursive handle_option calls. */
bool
c_common_handle_option (size_t scode, const char *arg, int value,
int kind, location_t loc,
const struct cl_option_handlers *handlers);
它本质上是一个简单的选项设置切换梯子,由scode
- 哪个
是OPT_std_c__11
供选择-std=c++11
- 毫无疑问,它
把一个-std
无论之前生效的设置是什么,选项设置都会生效。您可以查看除以下以外的分支master
(gcc-{5|6|7}-branch
)得出同样的结论。
发现依赖于有效性的 GCC 构建系统脚本并不罕见
通过附加新设置来覆盖选项设置。从法律上讲,这
通常指望未记录的行为,但有更好的
俄罗斯加入北约的可能性大于海合会停止采取最后一种设置的可能性
它解析互斥体选项。