当我为 long double
变量类型赋值时,我遇到了一个奇怪的错误。 (PowerPC架构,gcc v4.9.2)
具体来说:
const constexpr long double DEGREE_TO_RAD = 0.0174532925199432954743716805978693;
const constexpr long double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
似乎会导致以下编译器错误:
error: ‘(1.0e+0l / 1.74532925199432954743716805978693e-2l)’ is not a constant expression
const constexpr long double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
我不是 C++ 专家;这是我试图专门为我的开发机器环境构建的软件。然而,我的研究使我得到了以下花絮:
On some PowerPC and SPARCv9 machines,
long double
is implemented as a double-double arithmetic, where along double
value is regarded as the exact sum of two double-precision values, giving at least a 106-bit precision; with such a format, thelong double
type does not conform to the IEEE floating-point standard. Otherwise,long double
is simply a synonym fordouble
(double precision). [wiki]
这让我相信构建失败是由于 long double 在我的架构中与标准 x86 有不同的解释。将源代码中的 long double
更改为 double
可以使编译成功。这是巧合吗?在这种情况下,为什么 g++ 会对此大发雷霆?
最佳答案
这是与 constexpr
相关的错误(或可能是多个错误) . PowerPC 的 Clang does compile your snippet没有任何问题。如果你删除 constexpr
然后 GCC 也在 C mode 中正确编译它和 C++ mode
关于bug,第一个issue可以从GCC的报错信息中看出
↓ ↓ error: ‘(1.0e+0l / 1.74532925199432954743716805978693e-2l)’ is not a constant expression const constexpr long double RAD_TO_DEGREE = 1. / DEGREE_TO_RAD;
没有 L
源文件中的后缀,但不知何故它出现在错误输出中。如果我通过添加后缀来更正代码,它仍然会因同样的原因而失败。我没有用于 PowerPC 的较新版本的 GCC,所以我无法验证这一点,但错误出现在 GCC 4.8.5 and 6.3.0, and even AT12.0 (which is based on GCC 8) on Compiler Explorer 中。
确实 PowerPC 使用了 double-double arithmetic对于 long double
默认情况下,但浮点格式只是对用户透明的内部实现细节。它应该不会影响正确代码的编译。大多数嵌入式系统没有浮点支持,大多数当前平台没有 128 位硬件 long double
.他们都使用软件来进行这些操作,但浮点代码仍然可以在它们上正常编译。无论格式如何,有效代码都应该编译并
如果我 specify -mabi=ieeelongdouble
它们确实有效尽管。在这里你也可以清楚的看到使用和不使用L
的区别。后缀,因为没有它,文字是 double
并将在 double
build 转换为 long double
之前的精度,这意味着您将丢失 double 以外的所有数字。 如果不使用 double
,请记住始终在浮点类型中使用正确的后缀
.LC0: # 1./0.0174532925199432954743716805978693
.long 1074055773
.long 3248897055
.long 2108954270
.long 2705146754
.LC1: # 1.L/0.0174532925199432954743716805978693L
.long 1074055773
.long 3248897055
.long 2108954270
.long 2705146739
other platforms 的常量相同使用 IEEE-754 quadruple-precision floating-point format
关于c++ - 使用 gcc 编译时 PowerPC 上的 long double 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48553127/