编译和工作的错误的静态const初始化 [英] Wrong static const initialization that compiles and works

查看:649
本文介绍了编译和工作的错误的静态const初始化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

据我所知,您只能在声明的同一行中初始化static const成员如果它们是整数类型

As far as I know, you can only initialize static const members in the same line of their declaration if they are integral types . However, I was still able to initialize and use some static const doubles:

// compiles and works, values are indeed doubles
struct Foo1{ 
    static const double A=2.5;
    static const double B=3.2;
    static const double C=1.7;
};

// compiles, but values are cast to int
struct Foo2{
    static const int A=2;
    static const int B=3;
    static const double C=B/A; //becomes 1
};

// does not compile, Foo3::B cannot appear in a constant-expression
struct Foo3{ 
    static const int A=2;
    static const double B=3;
    static const double C=A/B; 
};

// does not compile, a cast to a type other than an integral or enumeration
// cannot appear in a constant-expression
struct Foo4{ 
    static const int A=2;
    static const int B=3;
    static const double C=(double)A/B; 
};

Foo2编译,但Foo2 :: C变为1,因此可能会被视为一个int数字一。 Foo3和Foo4甚至不编译,如预期。但是,我不明白为什么Foo1都编译和工作正常。这个具体用法是否被接受?是因为一些优化吗? (我试过使用-O1和-O0)

Foo2 compiles but Foo2::C becomes 1, so maybe it is treated as an int as it is numerically one. Foo3 and Foo4 don't even compile, as expected. However, I don't understand why Foo1 both compiles and works correctly. Is this specific usage accepted? Is it because of some optimization? ( I've tried using -O1 and -O0)

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

Note: using GNU 5.2.0 with cmake and setting the standard to C++98. Switching to C++11 works fine ( that is, does not compile and asks to switch those members to constexpr).

推荐答案

Foo1 案例确实不符合规定,使用 -std = c ++ 98 -pedantic gcc将警告如下( see it live ):

The Foo1 case is indeed non-conforming and if we build using -std=c++98 -pedantic gcc will warn as follows (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 不会产生任何错误或警告( 查看实时

While compiling without -pedantic does not yield any error or warning (see it live)

因此,是一个扩展,如果我们使用 -std = C ++ 98 -pedantic 使用clang,我们看到这个消息:

So this must be an extension and if we use clang using -std=C++98 -pedantic we see this message:

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;
                    ^ ~~~

这似乎确认这是一个扩展。

which seems to confirm this is an extension.

这种对浮点的限制保留在C ++ 11中,以保持与C ++ 03的兼容性,并鼓励对constexpr的一致使用,参见:对于double类型的静态类成员,常量表达式初始化器

This restriction on floating point was kept in C++11 to remain compatible with C++03 and to encourage consistent use of constexpr see: Constant expression initializer for static class member of type double.

Foo2 初始化 C 作为扩展名,除法的结果将是 int ,因为类型

This is also the case for Foo2 initializing C is allowed as an extension, the result of the division will be int since the type of the result depends on the type of the operands and does not depend on what you assign it to.

更新

这是折旧的扩展 a>:


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

G++ allows static data members of const floating-point type to be declared with an initializer in a class definition. The standard only allows initializers for static members of const integral types and const enumeration types so this extension has been deprecated and will be removed from a future version.

有一个更详细的 gcc错误报告,讨论扩展程序的有效性及其周围的其他相关问题。

There is a more detailed gcc bug report that discusses the validity of the extension and other related issues around it.

-pedantic 本身就足以将此变成错误,有一个 gcc错误报告覆盖

It seemed odd that using -pedantic was sufficient by itself to turn this into an error, there is a gcc bug report that covers that.

这篇关于编译和工作的错误的静态const初始化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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