原生 C 有公共符号吗?

Does native C have common symbol?

在 GCC10 中,gcc 默认为 fno-common。也就是说,所有暂定的符号都不通用。我认为 gcc 符合 C 规范,但在本机 C 程序中似乎没有公共符号。常用符号只用于扩展语法吗?

Does native C have common symbol?

阅读 C11 标准 n1570它的索引甚至没有提到常用符号。

另请仔细阅读 documentation of GCC and this draft 报告。

也许你指的是ELF file format used on Linux for object files and executables. There you can find a mention of common symbols, which tend to be deprecated .... Read the Linux ABI specification, etc here

我的建议是在某些头文件中将所有 public 符号声明为 extern(在大多数 *.c 文件中为 #include-d),并定义他们一次(没有extern)在单个 translation unit. You could use simple preprocessor tricks (such as X-macros).

您可能有兴趣适当地使用 C 代码生成器,例如 lemon or SWIG, or develop your script (with GNU awk or Guile or Python or GPP etc... ....) for simple metaprogramming techniques (autoconf could be inspirational) generating some C code. Configure your build automation tool (GNU make, ninja...)。

您可能有兴趣使用 static analyzer options and precompiled headers of recent GCC. Look also into Clang static analyzer and clang tidy and Frama-C

你肯定想通过-Wall -Wextra -g -H to gcc and read How to debug small programs and Modern C.

不,它与 "extension syntax" 无关,也与作为语言结构的 "common symbols" 无关。它只是指变量声明在文件范围内的行为。

C 说如果你在文件中放置像 int i; 这样的声明,并且不在其他任何地方详细说明它,那么它将具有外部 linkage 并且将被视为被定义为具有值 0。这称为 "tentative definition"。不同文件中的同名声明,如果有external linkage,都指向同一个变量。通常使用外部 linkage 的方法是在一个文件中定义一个变量,并在任何其他使用它的文件中使用 extern 声明。

在具有 -fcommon 的 GCC 中,同一变量的暂定定义可以出现在多个文件中。 GCC 将在 link 时间解决这个问题,并为变量分配一次存储空间(初始化为零)。

在带有 -fno-common 的 GCC 中,暂定定义会在编译文件时尽快解析为定义。如果多个文件包含一个变量的暂定定义,那么这将在 link 次导致多重定义错误。

据我所知,C 标准不要求或禁止 任一 行为。特别是C没有C++的"one definition rule"。然而,-fno-common 行为通常不那么令人惊讶,更快地捕获被遗忘的 extern,并允许编译器更好地优化(因为它在编译时确切地知道变量所在的位置,而不是等到以后才发现).由于这些原因,GCC 中的默认值已更改。