可以在GCC中将std = c99设置为默认值吗?

Gra*_*ing 2 c gcc c99

首先,是否可以编辑GCC命令行设置,以便我不必每次都使用-std = c99标志进行编译?

其次,为什么c99不是默认行为?使用c99进行编译允许某些现代编程约定,例如在for循环中创建和初始化索引变量.

for(int i = 0; i < 10; i++) {...
Run Code Online (Sandbox Code Playgroud)

没有c99标志,这是不可能的,我将不得不在自己的线上声明,我认为这是愚蠢的.为什么GCC默认不会用C99编译?(正常好奇,不抱怨.请不要抨击)

谢谢.

nod*_*kai 8

如果你真的-std=c99每次添加,你可以修改所谓的"spec文件",这是gcc命令的配置文件.请注意,该gcc命令实际上是一个编译器驱动程序,它只能在较窄的意义上调用编译器(后者是ccl或者cc1plus在GCC工具链的情况下).

现在修改specs文件有点棘手,因为gcc默认情况下它只存在于命令的二进制文件中.这是因为很少有人想为自己的目的修改它.

查找gcc命令尝试以这种方式查找任何规范文件的路径,

$ strace -e file gcc 2>&1 | grep specs
access("/usr/lib/gcc/x86_64-linux-gnu/4.6/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../x86_64-linux-gnu/lib/x86_64-linux-gnu/4.6/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/4.6/../../../../x86_64-linux-gnu/lib/specs", R_OK) = -1 ENOENT (No such file or directory)
access("/usr/lib/gcc/x86_64-linux-gnu/specs", R_OK) = -1 ENOENT (No such file or directory)
Run Code Online (Sandbox Code Playgroud)

然后通过转储内置规范文件在上述位置之一创建模板文件:

$ sudo bash -c 'gcc -dumpspecs > /path/to/specs'
Run Code Online (Sandbox Code Playgroud)

此时,输出gcc -v应该由此改变

$ gcc -v
Using built-in specs.
(...snip...)
Run Code Online (Sandbox Code Playgroud)

喜欢的东西

$ gcc -v
Reading specs from /usr/lib/gcc/x86_64-linux-gnu/4.6/specs
(...snip...)
Run Code Online (Sandbox Code Playgroud)

现在您需要根据需要修改specs文件.语法确实很神秘,但你可以用你的想象力.提示:你应该看到类似的东西

*cpp_options:
%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w} %{f*} %{g*:%{!g0:%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*} %{undef} %{save-temps*:-fpch-preprocess} %(ssp_default)
Run Code Online (Sandbox Code Playgroud)

看看这部分:

%{std*&ansi&trigraphs}
Run Code Online (Sandbox Code Playgroud)

这是在命令构造预处理器的完整命令行-std=c99之前扩展到gcc的位置cpp.您应该能够-std=c99在它之前插入,以便它作为-std选项的默认值.做同样的事情*cc1_options实际上对你的目的更重要.


Chr*_*der 5

我不知道这个问题的答案,但你应该只使用一个 makefile。

非常简单的makefile:

CC = gcc
CFLAGS = -g -Wall -std=c99
OBJECTS = *.c  #Source files
NAME = FILENAME  #Desired filename
TODELETE = $(NAME) *.o # the *.o should be the same as the objects
LIBS = NECESSARY_LIBS #remove line if no external libraries needed

mt-collatz : $(OBJECTS)
<INSERT TAB>$(CC) $(CFLAGS) $(OBJECTS) -o $(NAME) $(LIBS)

.PHONY: clean
clean:
<INSERT TAB>rm -f $(TODELETE)
Run Code Online (Sandbox Code Playgroud)

键入 make 进行编译, make clean 以删除已编译的对象。删除带有 # 符号的注释,并添加一个选项卡,其中显示 INSERT TAB,因为我不知道如何在 SO 上执行此操作。

您实际上不必删除 OBJECTS 和 TODELETE 中的 *.c 和 *.o,但是如果您最终得到多个具有 main 函数的文件,它会抱怨。