34

在 Stroustrup 的新书“C++ 编程语言 - 第四版”的 10.5.1 节中,他说,在执行算术运算之前,整数提升用于从较短的整数类型创建整数,类似地,浮点提升是用于从浮点数中创建双打。

我使用以下代码确认了第一个声明:

#include <iostream>
#include <typeinfo>

int main()
{
    short a;
    short b;
    std::cout << typeid(a + b).name() << std::endl;
}

这将使用 vc++ 输出“int”,使用 gcc 输出“i”。

但是用浮点数而不是短裤测试它,输出仍然是“float”或“f”:

#include <iostream>
#include <typeinfo>

int main()
{
    float a;
    float b;
    std::cout << typeid(a + b).name() << std::endl;
}

根据 Stroustrup 的说法,浮点提升规则没有例外,所以我期望“double”或“d”作为输出。

提到的关于促销的部分是错误的还是不清楚?C++98 和 C++11 在类型提升方面有什么不同吗?

4

2 回答 2

29

我不知道 Stroustrup 的书到底说了什么,但按照标准,这种情况下floats 不会转换为doubles 。在应用大多数算术二元运算符之前,先应用 5p9 中描述的常用算术转换:

  • 如果任一操作数属于范围枚举类型 (7.2),则不执行任何转换;如果另一个操作数的类型不同,则表达式格式错误。
  • 如果任一操作数是 long double 类型,则另一个应转换为 long double。
  • 否则,如果任一操作数为双精度,则另一个应转换为双精度。
  • 否则,如果任一操作数为浮点数,则另一个应转换为浮点数。
  • 否则,应在两个操作数上执行积分提升 (4.5)。[...]

积分提升是导致两个shorts 转换为ints 的原因。但是两个floats不会double按照这些规则转换成s。如果将 a 添加float到 a doublefloat则将转换为 a double

以上来自C++11。C++03 包含相同的规则,除了引用范围枚举的规则。

于 2013-06-20T14:02:31.937 回答
6

与此同时,Stroustrup 似乎认识到引用句子不正确或至少具有误导性。他从第 10.5.1 节中删除了关于浮点提升的句子。

请参阅Stroustrup 网页上第 4 版的第 3 次印刷勘误表:

第 267 页:s/类似地,浮点提升用于从浮点数中创建双精度//

(备注:表达式 s/regexp/replacement/ 类似于sed unix 工具语义。它搜索模式regexp并将其替换为replacement。在我们的例子中没有。)

于 2014-09-20T18:57:37.620 回答