【问题标题】:gcc permanently change c standardgcc永久更改c标准
【发布时间】:2023-11-14 04:50:01
【问题描述】:

有没有办法告诉 gcc 在编译 c 文件时默认使用 c99 标准? 我想避免一直给它-std=c99 参数。 我假设我可以通过在 .bashrc 文件中创建别名来做到这一点,但似乎相当不雅。

【问题讨论】:

  • 实际上,bashrc 中的别名是许多此类“自定义”问题的优雅(和标准)解决方案,尽管我不建议掩盖名称 gcc——你应该命名你的别名是别的东西。 (例如,ll 通常别名为 ls -lA。)

标签: c gcc standards c99


【解决方案1】:

您可以调用c99 而不是gcc(gcc 的包装器,如果它在您的系统上可用)或尝试修改您的 gcc 规范文件。更多信息在这里:http://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Spec-Files.html

【讨论】:

  • c99 实际上是所有 POSIX 平台的先决条件。但请注意,它不一定指向相同版本的 gcc。即在 OS X 上,c99 是一个完全过时的 gcc 版本。
【解决方案2】:

这是一个意想不到的答案。使用 Makefile!

优点:

  • 只需输入make 即可构建
  • 在构建过程中会自动处理所有选项。
    当您使用它时,请继续并启用所有警告,这是很好的做法。 See this
  • 易于扩展到多个源文件
  • 可以处理涉及不同工具的多步骤构建

缺点:

  • 另一个学习工具,另一个错误。

考虑这个来源:

#include <stdio.h>

int main() {
    printf("Hello!\n");
    int x = 4;
    printf("%d\n", x);
    return 0;
}

你可以像这样制作一个 Makefile:
(免责声明,我其实不知道怎么写)

CC=gcc
CFLAGS=-Wall -pedantic -std=c99
LDFLAGS=
SOURCES=$(wildcard *.c)
OBJECTS=$(SOURCES:.cpp=.o)
EXECUTABLE=hello

.PHONY: clean

all: $(SOURCES) $(EXECUTABLE)

$(EXECUTABLE): $(OBJECTS) 
    $(CC) $(LDFLAGS) $(OBJECTS) -o $@

.cpp.o:
    $(CC) $(CFLAGS) $< -o $@

clean:
    rm -f *.o $(EXECUTABLE)

它为我构建。

同样,如果您删除 -std=c99,它不应该是有效的 C89 代码,实际上,输入 make 会导致构建错误。

【讨论】:

  • “另一种学习工具,另一种错误......免责声明,我实际上不知道如何写它们” 无意冒犯,但我认为你已经严重破坏了你自己的答案与那些陈述。构建系统对于非平凡的项目非常重要,但是 (1) 原始 Make 是 (IMO) 构建系统的一个非常糟糕的选择,并且 (2) 构建系统对于单文件“沙箱”并不是真正必要或有用的——样式编译。
  • 实际上,在这里只定义CFLAGS(并且在Makefile中什么都不做)是一个不错的解决方案; make 将使用默认参数自动生成目标(我没有意识到这一点)。见*.com/a/32485029/1858225
【解决方案3】:

自定义编译建议您具备编译器、标准和基本标志/选项的工作知识。为此,我建议你在.bashrc.tcshrc等中设置shell变量,并在命令行中使用。

由于方言的选择会影响链接:CC="gcc -std=c99",因此您可以使用$CC -c -O2 ... foo.c 调用单独的编译命令,并且还被选为configure 脚本等的默认值。当然,您总是可以用CC="gcc -std=c90"CC="clang" 覆盖configure 脚本。这同样适用于首选的CFLAGS 值,例如,

CFLAGS="-pipe -W -Wall -O2 -march=core2"

允许$CC $CFLAGS -c foo.c 命令,并且默认情况下这两个环境变量都与配置脚本一起使用,除非您明确覆盖它们。我认为这比别名更有用。但也许我已经习惯了自己的设置:)

【讨论】:

  • 我已经修复了一些变量赋值,它们需要在 Bash(可能还有大多数或所有其他标准 shell)中正确处理引号。我认为当您对变量赋值的建议结合使用时,别名将是一个很好的解决方案:alias cc="$CC $CFLAGS".
【解决方案4】:

在我看来,这两种建议的解决方案几乎都是你想要的,但都没有达到。

Makefile 解决方案

正如here 所见,通过在您的Makefile 中定义变量但 定义目标,您可以使用make 命令,就像自定义传递到GCC。因此,如果您在“沙盒”目录(或您在真实构建系统之外编译的任何地方)创建 Makefile 并定义 C*FLAGS 变量,您基本上会得到您想要的。一个示例 Makefile:

CFLAGS=-Wall -std=c99
CXXFLAGS=-Wall -std=c++14

现在,make foo 会将foo.c 转换为名为@9​​87654329@ 的可执行文件。

如果您想在多个目录中执行此技巧,请将您的 makefile 放在一个已知位置——例如,~/sandbox——并在您的 .bashrc 中创建以下别名(或类似名称):

alias usestdmake="ln -s ~/sandbox/Makefile"

然后你可以在你机器上的任何地方快速编译单个文件:

usestdmake
make foo

这具有为输出可执行文件提供适当名称(在本例中为foo)的额外优势。它的缺点是禁用您的编译命令的制表符补全(make fo&lt;tab&gt; 什么都不做,至少在我的系统上是这样)。

bashrc解决方案

Brett Hale 的回答中提到的 CC/CFLAGS 变量是相当标准的,因此在 bashrc 中定义它们可能是个好主意。然后,您可以在别名中使用这些变量。

在你的.bashrc:

CFLAGS="-Wall -std=c99"
CC=gcc
# Use single-ticks to ensure that the variables are evaluated when the alias is evaluated.
alias mycc='$CC $CFLAGS'

在命令行上:

cc foo.c    # Compile with default CFLAGS
CFLAGS="$CFLAGS -O2" cc foo.c    # Compile with modified CFLAGS

【讨论】: