我目前想知道为什么在编译/链接小型 C 程序期间我没有从 GCC 收到错误。
我在 version.h
中声明了以下字符串:
const char* const VERSION;
在version.c
中我设置了变量的初始化:
const char* const VERSION = "0.8 rev 213";
没问题。我可以在程序的其余部分使用该字符串。
如果 c 文件丢失,在编译/链接期间不会发生错误,但程序在尝试访问变量时会失败并显示 SIGSEGV(当然)。
我设置变量 VERSION
的方法是否正确,还是有更好的方法?或者在编译/链接期间是否有可能出错?
最佳答案
您在 header 中定义了(不仅仅是声明)了一个变量。
如果您从多个源文件中包含此 header ,则行为是未定义。以下是标准的相关引述:
J.2 Undefined behavior
…
An identifier with external linkage is used, but in the program there does not exist exactly one external definition for the identifier, or the identifier is not used and there exist multiple external definitions for the identifier.
…
您在这里依赖于特定于 GCC 的(实际上对许多编译器来说很常见,但仍然是非标准的)行为,即合并重复的暂定 数据定义。查看 -fcommon
和 -fno-common
GCC 编译标志的帮助。并非所有编译器都以这种方式运行。从历史上看,这是链接器的常见行为,因为在出现 C 之前,这就是 Fortran 的工作方式。
假设此语言扩展,定义之一(具有显式初始化程序的定义)初始化变量以指向您的字符串文字。但是如果你省略这个定义,它将保持零初始化。也就是说,它将是一个常量空指针。不是很有用。
长话短说,永远不要那样做。为了在 header 中声明(但不定义)全局变量,请使用 extern
。如果您这样做,并试图在别处省略定义,您将可能遇到链接器错误(尽管标准不要求对此违规进行诊断,但所有已知的实现都会产生一个)。
关于c - 未初始化的 C 字符串没有警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51135420/