在这样的 C 程序中
double x = 1;
x %= 1.;
二进制 % 的无效操作数(有 'double' 和'long double')
由此可知表达式1.的类型为long double。
相同的代码,但专业人士只显示double http://ideone.com/nd49YK:
二进制“operator%”的“double”和“double”类型的无效操作数
是的,这样的加号检查也适用于双http://ideone.com/HCw0GG:
auto x = 1.;
cout
<< sizeof (double) << ' ' // 8
<< sizeof (long double) << ' ' // 12
<< sizeof x << ' ' // 8
<< sizeof 1. << endl; // 8
事实证明,C++ 推断类型double,而不是long double。
那么,这是 C 和 C++ 之间的差异之一,还是编译器错误?
constant 的正确类型1.是什么,它是否依赖于语言?
视图常量在 C++ 和 C 中
1.都有一个类型。doubleC
C++
ideone.com 上使用的编译器是 version
5.1.1 20150711。因此,如果有人有机会的话,在本地驱动它可能是有意义的。与 goodbolt (5.1) 类似的编译器会抛出正确类型的错误:一个可能的原因在于 value
FLT_EVAL_METHOD,它指定了内部操作的计算精度。对于 ideone,这个值为2,因为 使用 32 位编译器:那些。所有浮点计算都依赖于
long double.虽然,事实上,这不应该影响实常量的类型。
事实证明,您可以通过添加键将 64 位 g++ 编译器上的值
FLT_EVAL_METHOD从0更改为:2-mfpmath=387结果:
在这种情况下,第二个参数
long double的错误消息也将类型推断为 ideone 上的原始类型(对于 32 位):Clang 需要一个不同的键:
-mno-sse. 在这种情况下,两种类型的诊断消息都已显示double:同时,我觉得第一个应该还是保留的
int。总而言之,我们可以说诊断消息中的两个编译器在推断操作数的原始类型方面都存在问题。
浮点常量
1.的类型为double。像这样的错误信息
与 C 编译器如何处理表达式中浮点操作数的转换有关。例如,编译器可能会将浮点操作数转换为范围和精度超过基础浮点类型的相应范围和精度的格式。这样做是为了在计算表达式及其复合子表达式的过程中获得更准确的结果。
来自 C 标准(5.2.4.2.2 浮动类型的特征
<float.h>)如果您在
FLT_EVAL_METHOD定义名称的地方包含一个标头,那么您可以获得以下结果控制台输出:
从上面引用的 C 标准中可以看出,这意味着常量将被转换为 type
long double。但是,如果不包含头文件
<float.h>,编译器似乎默认使用此选项来评估浮点表达式。决定通过
sizeofhttp://ideone.com/r54ZSs进行检查:收到8 12 8。也就是平时的这个
double。显然,错误分析中出现了一些错误,因为只有在那里它接收到不同类型的http://ideone.com/45lztk: