【问题标题】:Can one set std=c99 in GCC as a default? [duplicate]可以将 GCC 中的 std=c99 设置为默认值吗? [复制]
【发布时间】:2014-12-23 08:26:14
【问题描述】:

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

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

for(int i = 0; i < 10; i++) {...

如果没有 c99 标志,这将是不可能的,我必须在外部声明它自己的行,我认为这很愚蠢。为什么 GCC 不默认使用 C99 编译? (合法的好奇,不是抱怨。拜托,不要抨击)

谢谢。

【问题讨论】:

  • 我想你可以这样做alias gcc="gcc -std=c99"
  • 技术上C99 support 不完整。 standards page 说:The default, if no C language dialect options are given, is -std=gnu90; this is intended to change to -std=gnu11 in some future release.
  • @remyabel:是的,每当下一个版本出来时,他们都会更新这个崇高的目标。
  • 使用 makefile 是隐藏所有细节的好方法。然后你只需输入“make”。
  • @mafso 不是真的。看来手册自相矛盾。 C Dialect Options‘gnu1x’ GNU dialect of ISO C11. This is the default for C code.

标签: c gcc c99


【解决方案1】:

我不知道这个问题的答案,但你应该只使用一个 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)

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

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

【讨论】:

    【解决方案2】:

    最好的方法是使用Makefile,例如answered by Christopher Schneider。另见this example

    你也可以有一个shell脚本(在你的$PATH中,在/usr/bin之前),甚至可以命名为gcc(即$HOME/bin/gcc$HOME/bin放在之前 /usr/bin/在您的$PATH 中,查看您的~/.bashrc),它使用所需的选项调用/usr/bin/gcc。对于交互式使用,您还可以alias gcc 命令。

    最后,GCC 正在使用spec-files。您可以更改系统的规范文件以添加特定选项(对于cc1)。我不确定这是个好主意。

    GCC 的下一个版本 (5.0) 将默认为 C11

    【讨论】:

      【解决方案3】:

      您可以将此添加到您的~/.profile 或您平台上的类似内容中:

      CFLAGS="$CFLAGS -std=c99"
      

      然后 Make 和类似的工具应该每次都选择它。

      至于为什么不是默认:向后兼容!

      【讨论】:

        【解决方案4】:

        如果您真的想每次都添加-std=c99,您可以修改所谓的“规范文件”,即gcc 命令的配置文件。请注意,gcc 命令实际上是一个编译器驱动程序,它只调用狭义上的编译器(在 GCC 工具链的情况下,后者是 cclcc1plus。)

        现在修改 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)
        

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

        $ sudo bash -c 'gcc -dumpspecs > /path/to/specs'
        

        此时,gcc -v 的输出应该从这里改变

        $ gcc -v
        Using built-in specs.
        (...snip...)
        

        类似

        $ gcc -v
        Reading specs from /usr/lib/gcc/x86_64-linux-gnu/4.6/specs
        (...snip...)
        

        现在您需要根据需要修改规范文件。语法确实很神秘,但你可以发挥你的想象力。提示:你应该看到类似

        *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)
        

        看这部分:

        %{std*&ansi&trigraphs}
        

        这是-std=c99gcc 命令为预处理器cpp 构造完整命令行之前扩展的位置。您应该能够在它之前插入-std=c99,以便它作为您自己的-std 选项的默认值。对*cc1_options 执行相同的操作,这实际上对您的目的更重要。

        【讨论】:

          猜你喜欢
          • 2011-01-12
          • 1970-01-01
          • 2011-04-05
          • 2012-08-13
          • 1970-01-01
          • 2017-02-22
          • 1970-01-01
          • 1970-01-01
          • 2017-06-09
          相关资源
          最近更新 更多