Can a static variable be initialized with a static constant?

北慕城南 提交于 2020-04-13 03:53:50

问题


In this answer I basically needed static int n = -1; inside a function. I wanted to avoid magic numbers so I used this instead:

double f(int i)
{
    static const int sentinel = -1;
    static int n = sentinel;

    if (n == sentinel)
    // ...
}

It was however pointed to me that this is not conformant to standard because sentinel is not a (compile time) constant.

This makes sense to me since I know constant integers were made usable in compile time expressions (e.g. size of arrays) in C++. However gcc, clang and icc >v16 compile this code without any warning. Only icc <=v16 and MSVC give this warning/error (see on godbolt).

What does the C Standard say? Does this change between various versions of the standard (c90, c99, c11)? If this is not conformant, can we get a warning on gcc and clang? If it is conformant why do old icc and MSVC give errors?


回答1:


static const int sentinel = -1; static int n = sentinel; is conforming C code. It is not strictly conforming C code.

C 2018 defines a strictly conforming program to be one that “shall use only those features of the language and library specified in this document” (C 2018 4. 5). Strictly conforming programs are those that only use the core language that is fully defined in the standard. It defines a conforming program to be one that is “that is acceptable to a conforming implementation” (4. 7). For hosted implementations, a conforming implementation, is one that accepts any strictly conforming program (4. 6)—that is, any compiler or other implementation that supports the core C language but that may also have extensions.

6.7.9 4 says “All the expressions in an initializer for an object that has static or thread storage duration shall be constant expressions or string literals.” sentinel is clearly not a string literal. Is it a constant expression? Constant expressions are defined in 6.6. With one exception, they must have operands that are integer constants (that is, literals such as 37), sizeof expressions that yield integer constants, _Alignof expressions, floating-point constants, enumeration constants, character constants, or unary & expressions with certain constraints. sentinel is none of these.

The exception is that paragraph 10 says “An implementation may accept other forms of constant expressions.” So, GCC and other compilers are free to accept this code if they wish, and therefore, since it is accepted by a conforming implementation, it is conforming code. However, since it is implementation-defined whether this is accepted or not, it is not strictly conforming code.

This is substantially similar in prior C standards back to 1990, although there are minor changes, such as that _Alignof was not in early versions of the standard.



来源:https://stackoverflow.com/questions/61037093/can-a-static-variable-be-initialized-with-a-static-constant

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!