有没有一种方法可以抑制默认的GCC编译器选项?

3

我希望只使用我特别提到的编译器选项来编译C代码。因此,我需要以某种方式禁用所有自动设置的编译器选项。如何禁用默认的GCC选项,在每次编译时都会设置,并且不可见。我指的是使用以下命令可见的编译器选项 gcc -Q -v example.c 并导致以下输出:

GNU C (Ubuntu 4.8.4-2ubuntu1~14.04.3) version 4.8.4 (x86_64-linux-gnu)
    compiled by GNU C version 4.8.4, GMP version 5.1.3, MPFR version 3.1.2-p3, MPC version 1.0.1
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
options passed:  -v -imultiarch x86_64-linux-gnu example.c -mtune=generic
 -march=x86-64 -fstack-protector -Wformat -Wformat-security
options enabled:  -faggressive-loop-optimizations
 -fasynchronous-unwind-tables -fauto-inc-dec -fbranch-count-reg -fcommon
 -fdelete-null-pointer-checks -fdwarf2-cfi-asm -fearly-inlining
 -feliminate-unused-debug-types -ffunction-cse -fgcse-lm -fgnu-runtime
 -fgnu-unique -fident -finline-atomics -fira-hoist-pressure
 -fira-share-save-slots -fira-share-spill-slots -fivopts
 -fkeep-static-consts -fleading-underscore -fmath-errno
 -fmerge-debug-strings -fmove-loop-invariants -fpeephole
 -fprefetch-loop-arrays -freg-struct-return -fsched-critical-path-heuristic
 -fsched-dep-count-heuristic -fsched-group-heuristic -fsched-interblock
 -fsched-last-insn-heuristic -fsched-rank-heuristic -fsched-spec
 -fsched-spec-insn-heuristic -fsched-stalled-insns-dep -fshow-column
 -fsigned-zeros -fsplit-ivs-in-unroller -fstack-protector
 -fstrict-volatile-bitfields -fsync-libcalls -ftrapping-math
 -ftree-coalesce-vars -ftree-cselim -ftree-forwprop -ftree-loop-if-convert
 -ftree-loop-im -ftree-loop-ivcanon -ftree-loop-optimize
 -ftree-parallelize-loops= -ftree-phiprop -ftree-pta -ftree-reassoc
 -ftree-scev-cprop -ftree-slp-vectorize -ftree-vect-loop-version
 -funit-at-a-time -funwind-tables -fvar-tracking -fvar-tracking-assignments
 -fzero-initialized-in-bss -m128bit-long-double -m64 -m80387
 -maccumulate-outgoing-args -malign-stringops -mfancy-math-387
 -mfp-ret-in-387 -mfxsr -mglibc -mieee-fp -mlong-double-80 -mmmx -mno-sse4
 -mpush-args -mred-zone -msse -msse2 -mtls-direct-seg-refs
Compiler executable checksum: a0a649d344b1ed798e33d30772d46437

这里默认的编译选项可以看作是启用的选项。我要如何禁用其中大部分选项而不使用-fno-...等方式?有没有一种简单的方法来正确地禁用默认的编译选项呢?


1
你希望通过关闭所有 -f... 选项获得什么?请注意,其中一些选项无法“关闭”,因为它们在两个不同的选择之间进行选择,例如 -mlong-double-80 在 128 位和 80 位 long double 之间进行选择。 - fuz
我想关闭我所知道的所有默认编译器选项。之后,我只想设置我主动设置的编译器选项。这是为了真正知道编译某个代码所激活的编译器选项是必要的。 - Maximilian
@FUZxxl:当所有选项都被禁用时,gcc处理的方言类似于1990年代流行的方言,其中包括许多有用的功能和保证,这些保证被省略在标准中,因为它们的成本可能超过了其收益。例如,如果代码需要将有符号值按正整数比例缩放,我认为gcc现在将支持x<<=y;而不是要求例如x=(int32)((uint32_t)x)<<y);,但程序员无法知道下一个gcc版本是否需要额外的-fno-silly-signed-shift才能使其工作。 - supercat
1个回答

2
使用以下脚本生成所有关闭的-f选项列表:
gcc -Q --help=optimizers | sed -e '/^[^[]*$/d' -e 's/ *\[.*$//' -e 's/^  -f/ -fno-/'

将结果保存在名为options.txt的文件中,并使用@-语法将其传递给gcc:

gcc @options.txt ...

请注意,这并不会“关闭”其他选项,例如-m...选项。大多数选项也无法被“关闭”,因为它们不是开关或者关闭它们会改变ABI。

有没有什么明智的方法可以确保在更新编译器时,不会默认启用任何添加到新版本gcc中的“优化”功能? - supercat
@supercat 关闭功能标志并不能保证编译器更加宽容。gcc是标准C的编译器;如果您想编译传统C,请考虑使用其他编译器,如pcc。 - fuz
“标准C”是一个神话。《一项程序规则》清楚地表明,标准的作者们希望实现提供超出明确要求的行为,因为它允许这种可能性(并且理由也承认了这一点),即实现可以完全符合标准但却毫无用处。如果标准的作者们不打算让实现在uint1=ushort1*ushort2;的结果介于INT_MAX+1u和UINT_MAX之间时如何处理,你能否提出任何原因... - supercat
如果没有充分的理由要改变,那么就会继续保持原样吗?在类型别名规则不存在的情况下,共同初始序列规则与关于联合和成员类型之间转换的规则相结合,意味着一个结构体指针可以用来检查另一个结构体的共同初始序列,正是这种能力使得共同初始序列规则非常有用;我认为标准从未打算消除这一点,但是gcc没有提供符合标准的方式来接受结构体指针的函数... - supercat
即使按照单一程序规则的思维方式阅读标准会表明标准确实定义了一种方法,但gcc却简单地忽略它,并将其用于检查任意对象的公共初始序列成员。如果gcc的作者不愿意承诺做任何标准未规定的事情,为什么有人要信任编译器呢? - supercat
@supercat 给 GCC 团队发送一个 Bug 报告。或者按照我之前的建议,使用另一个编译器。 - fuz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接