可以使用静态常量初始化静态变量吗? [英] Can a static variable be initialized with a static constant?

查看:99
本文介绍了可以使用静态常量初始化静态变量吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此答案中,我基本上需要在函数内部使用static int n = -1;.我想避免到处都出现幻数,所以我改用了它:

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

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

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

但是有人指出,这不符合标准,因为sentinel不是(编译时)常量.

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

这对我来说很有意义,因为我知道常量整数已在C ++中的编译时表达式(例如数组的大小)中可用.但是,gcc,clang和icc> v16会编译此代码,而不会发出任何警告.仅icc< = v16和MSVC给出此警告/错误(请参见 godbolt ).

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).

C标准怎么说?在不同版本的标准(c90,c99,c11)之间会发生变化吗?如果这不符合要求,我们可以在gcc和clang上得到警告吗?如果一致,为什么旧​​的icc和MSVC会给出错误消息?

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?

推荐答案

static const int sentinel = -1; static int n = sentinel;是一致的C代码.它不是严格符合C代码的语言.

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

C 2018将严格遵守的程序定义为仅应使用本文档中指定的语言和库的那些功能"(C 2018 4. 5).严格符合标准的程序是仅使用标准中完全定义的核心语言的程序.它将符合程序定义为符合标准的实现可接受的程序"(4. 7).对于托管实现,符合实现是接受任何严格符合程序(4. 6)的程序,即支持核心C语言但也可能具有扩展名的任何编译器或其他实现.

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说:对于具有静态或线程存储持续时间的对象,初始化程序中的所有表达式都应为常量表达式或字符串文字." sentinel显然不是字符串文字.它是一个常量表达式吗?常量表达式在6.6中定义.除了一个例外,它们必须具有整数常量(即37这样的文字),产生整数常量的sizeof表达式,_Alignof表达式,浮点常量,枚举常量,字符常量或具有某些约束的一元&表达式. sentinel都不是这些.

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.

唯一的例外是第10段说:实现可以接受其他形式的常量表达式."因此,GCC和其他编译器可以根据需要自由接受此代码,因此,由于符合标准的实现接受了它,因此它就是符合标准的代码.但是,由于是否接受此代码是实现定义的,因此它不是严格符合代码的代码.

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.

这与1990年以前的C标准基本相似,尽管有一些细微的变化,例如该标准的早期版本中没有_Alignof.

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.

这篇关于可以使用静态常量初始化静态变量吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆