[英]Can a static variable be initialized with a static constant?
在这个答案中,我基本上需要static int n = -1;
在 function 内。 我想避免到处都是幻数,所以我改用了这个:
double f(int i)
{
static const int sentinel = -1;
static int n = sentinel;
if (n == sentinel)
// ...
}
然而有人指出,这不符合标准,因为sentinel
不是(编译时)常数。
这对我来说很有意义,因为我知道常量整数可用于 C++ 中的编译时表达式(例如数组的大小)。 但是 gcc、clang 和 icc >v16 编译此代码时没有任何警告。 只有 icc <=v16 和 MSVC 会给出这个警告/错误(参见godbolt )。
C 标准怎么说? 这会在标准的不同版本(c90、c99、c11)之间发生变化吗? 如果这不符合要求,我们能否在 gcc 和 clang 上收到警告? 如果它是一致的,为什么旧的 icc 和 MSVC 会出错?
static const int sentinel = -1; static int n = sentinel;
符合 C 代码。 它不严格符合 C 代码。
C 2018 将严格符合的程序定义为“应仅使用本文档中指定的语言和库的那些功能”(C 2018 4. 5)。 严格符合标准的程序是那些只使用标准中完全定义的核心语言的程序。 它将符合标准的程序定义为“符合标准的实现可以接受”(4. 7)。 对于托管实现,一致实现是接受任何严格一致的程序 (4. 6) 的实现——即支持核心 C 语言但也可能具有扩展的任何编译器或其他实现。
6.7.9 4 说“具有 static 或线程存储持续时间的 object 的初始化程序中的所有表达式应为常量表达式或字符串文字。” sentinel
显然不是字符串文字。 是常量表达式吗? 常量表达式在 6.6 中定义。 除了一个例外,它们的操作数必须是 integer 常量(即诸如37
之类的文字)、产生 integer 常量的sizeof
表达式、 _Alignof
表达式、浮点常量、具有某些约束的枚举常量、字符常量或一元&
表达式. sentinel
不是这些。
例外是第 10 段说“一个实现可以接受其他 forms 的常量表达式。” 因此,如果 GCC 和其他编译器愿意,可以自由地接受此代码,因此,由于它被一致的实现接受,因此它是一致的代码。 但是,由于它是否被接受是实现定义的,因此它不是严格符合的代码。
这与 1990 年以前的 C 标准基本相似,尽管有一些细微的变化,例如_Alignof
不在标准的早期版本中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.