假设g++
与之一起运行是否安全
g++ -std=c++98 -std=c++11 ...
Run Code Online (Sandbox Code Playgroud)
将使用C++ 11编译?我没有在文档中找到明确的确认,但我看到-O
标志就是这样的.
在GCC手册并没有说明最后的互斥-std=...
指定的选项生效.第一次出现或最后一次出现是唯一的替代方案.有许多GCC标志从有限集中采用互斥的替代值 - 相互排斥,至少模数翻译单元的语言.我们简称为互斥选项.对于它的记录,最后一个设置生效,这似乎是一个随机的罕见.对于-O
您已经注意到的选项,以及相互排斥的警告选项(可能是其他选项)的一般术语,它都有记录.永远不会记录多重设置的第一个生效,因为它永远不会成立.
文档倾向于 - 具有不完美的一致性 - 关于unix-like操作系统中命令使用的历史惯例.如果命令接受互斥锁选项,则该选项的最后一次出现生效.如果命令是 - 异常 - 只在第一次出现选项时起作用,那么命令接受后续事件将是一个错误:它应该给出一个使用错误.
这是习惯和做法.自定义有助于使用尊重它的工具编写脚本,例如,脚本可以调用工具传递某些互斥锁选项的默认设置,但允许用户通过脚本的参数覆盖该设置,其值可以简单地附加到默认调用.
如果没有官方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;
}
Run Code Online (Sandbox Code Playgroud)
使用命令行:
g++ -std=c++98 -std=c++11 -m32 -m64 -O0 -O1 -g3 -g0 \
-Wformat -Wno-format -o wrong -o right main.cpp
Run Code Online (Sandbox Code Playgroud)
要求相互矛盾的选项对:
-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)]"
[]
Run Code Online (Sandbox Code Playgroud)
它不输出任何程序wrong
:
$ ./wrong
bash: ./wrong: No such file or directory
Run Code Online (Sandbox Code Playgroud)
它输出一个程序right
:
$ ./right
C++11
-1713064076
Run Code Online (Sandbox Code Playgroud)
它告诉我们它被编译为C++11
,而不是C++98
.
垃圾暴露的错误-1713064076
没有被诊断出来,因为它
-Wno-format
没有-Wformat
生效.
它是64位,而不是32位可执行文件:
$ file right
right: ELF 64-bit LSB shared object, x86-64 ...
Run Code Online (Sandbox Code Playgroud)
它被优化了-O1
,而不是-O0
因为:
$ "[$(nm -C right | grep str)]"
[]
Run Code Online (Sandbox Code Playgroud)
显示本地符号str
不在符号表中.
它不包含调试信息:
echo "[$(readelf --debug-dump right)]"
[]
Run Code Online (Sandbox Code Playgroud)
按照-g0
,不是-g3
.
由于GCC是开源软件,解决C程序员可用行为疑虑的另一种方法,至少是检查相关的源代码,可通过https://github.com/gcc-上的源代码git
控制获得.
镜子/ 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);
Run Code Online (Sandbox Code Playgroud)
它本质上是一个简单的切换梯形图,其选项设置由scode
- 枚举- OPT_std_c__11
用于选项-std=c++11
- 毫无疑问,-std
无论先前生效的设置如何,它都会使选项设置生效.您可以使用相同的结论来查看除master
(gcc-{5|6|7}-branch
)之外的分支.
通过附加新设置,找到依赖于覆盖选项设置的有效性的GCC构建系统脚本并不罕见.从法律上讲,这通常是指无证行为,但俄罗斯加入北约的可能性要大于GCC不再采用其解析互斥选项的最后设置.