错误的静态const初始化,编译和工作
Wrong static const initialization that compiles and works
据我所知,如果静态const成员是整型,则只能在声明的同一行初始化。但是,我仍然能够初始化和使用一些静态const double类型:
// 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,因为它是数字1。正如预期的那样,Foo3和Foo4甚至不能编译。然而,我不明白为什么Foo1既编译和工作正确。这种特殊用法被接受吗?是因为一些优化吗?(我试过使用- 01和- 0)
注意:使用GNU 5.2.0和cmake并将标准设置为c++ 98。切换到c++ 11工作得很好(也就是说,不编译并要求将这些成员切换到constexpr)。
Foo1
的情况确实不符合,如果我们使用-std=c++98 -pedantic
构建,gcc将发出以下警告(查看它的实时):
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
的情况下编译不会产生任何错误或警告(查看它的实时)
所以这必须是一个扩展,如果我们使用clang使用-std=C++98 -pedantic
,我们看到这个消息:
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的一致使用,参见:double类型静态类成员的常量表达式初始化式
这也是Foo2
初始化C
作为扩展允许的情况,除法的结果将是int,因为结果的类型取决于操作数的类型,而不取决于它的赋值对象。
更新
这是一个贬值的扩展:
c++允许在类定义中使用初始化式声明const浮点类型的静态数据成员。该标准只允许const整型和const枚举类型的静态成员的初始化式,因此该扩展已被弃用,并将从未来的版本中删除。
有一个更详细的gcc bug报告,讨论了扩展的有效性和其他相关问题。
看起来很奇怪,使用-pedantic
本身就足以将此转换为错误,有一个gcc错误报告涵盖了这一点。
- 编译在我的 Mac 上工作,但在集群 (Linux) 上不起作用
- std::unique_ptr 在 GCC 中工作,但不能在 Visual Studio 中编译
- 编译"运算符删除"时C++编译器如何工作?
- 在调试配置中编译工作正常,但发布会给出链接错误
- 重新编译我们的FORTRAN代码并在C++中使用后,我们的system()或C_str()命令无法正常工作
- 编译的谷歌协议缓冲区不工作(C++)
- 我的 PowerShell 脚本无法按预期工作(用于编译C++文件)
- C++编译器 g++.exe 无法编译简单的测试程序 - 确定 CXX 编译器是否工作失败
- C Visual Studio代码不使用工作区中的单个文件夹编译
- 如何编译Freetype(2)和Harfbuzz(带有Visual studio)使它们协同工作?
- CLion 无法解析类型 std::unordered_map,即使它提示我包含标头并且编译工作
- GCC 和 clang 抛出"no matching function call"但 msvc (cl) 按预期编译和工作
- 当其中一个函数未编译时,函数重载查找如何工作?
- C++程序使用 mingw 在 Linux 上交叉编译在 MSy2 中工作,但不能直接在 Windows 中工作
- 为什么三元运算符在编译时的工作方式与运行时不同?
- 初始化静态成员使编译工作.但是为什么
- 为什么这些标头仅在预编译的标题外工作
- &(array+1) 在 &arr 工作时给出编译错误
- 在我的工作目录中使用 glfw -3.2.1,如何使用 makefile 使用它进行编译
- 为什么在多个 cpp 文件中包含相同的标头,然后它们的编译工作