编译和工作的静态const初始化错误

时间:2015-09-27 23:38:31

标签: c++ gcc compiler-errors

据我所知,你只能在声明if they are integral types 的同一行初始化静态const成员。但是,我仍然可以初始化并使用一些静态const双精度数:

['bBBbAa', 'bBAa', 'bBCcBbAa', 'bBcCBbAa', 'bBcCaABbAa', 'bBcCaAAa', 'bBcCaACcBbAa', 'bBcCAa', 'bBcCCcBbAa']

Foo2编译,但Foo2 :: C变为1,所以也许它被视为一个int,因为它在数字上是一个。正如预期的那样,Foo3和Foo4甚至都没有编译。但是,我不明白为什么Foo1编译和正常工作。这种具体用法是否被接受?是因为一些优化? (我尝试过使用-O1和-O0)

注意:使用带有cmake的GNU 5.2.0并将标准设置为C ++ 98。切换到C ++ 11工作正常(即,不编译并要求将这些成员切换到constexpr)。

1 个答案:

答案 0 :(得分:11)

Foo1案例确实不符合规定,如果我们使用-std=c++98 -pedantic构建,gcc会发出以下警告( see it live ):

error: floating-point literal cannot appear in a constant-expression
 static const double A=2.5;
                       ^
warning: ISO C++ forbids initialization of member constant 'Foo1::A' of non-integral type 'const double' [-Wpedantic]

在没有-pedantic的情况下进行编译时不会产生任何错误或警告( see it live

所以这必须是一个扩展名,如果我们使用-std=C++98 -pedantic使用clang,我们会看到以下消息:

warning: in-class initializer for static data member of type 'const double' is a GNU extension [-Wgnu-static-float-init]
static const double A=2.5;
                    ^ ~~~

似乎证实这是一个扩展。

对浮点的这种限制保留在C ++ 11中以保持与C ++ 03兼容,并鼓励一致使用constexpr,请参阅:Constant expression initializer for static class member of type double

Foo2初始化C被允许作为扩展名也是如此,除法的结果将是 int ,因为结果的类型取决于操作数的类型,并不依赖于您为其分配的内容。

更新

这是depreciated extension

  

G ++允许使用类定义中的初始化程序声明const浮点类型的静态数据成员。该标准仅允许const整数类型和const枚举类型的静态成员的初始化器,因此不推荐使用此扩展,并将从将来的版本中删除。

有一个更详细的gcc bug report讨论了扩展的有效性及其周围的其他相关问题。

使用-pedantic本身就足以将其转化为错误似乎很奇怪,有一个gcc bug report that covers that