C和C++编译器在何时会隐式地将float转换或提升为double?

5
对于一个嵌入式项目,我想知道符合标准的C编译器(C99)和C++编译器(C++11)在什么情况下最可能将单精度变量/值隐含地提升为双精度浮点数。
我知道两种情况:
1.没有用“f”后缀的字面量。例如:3.14 2.将float传递给具有可变参数列表(...)的函数
还有其他情况吗?模板呢?
这个问题的答案对我也很有帮助 - 在此提供参考:这个问题

1
在所有使用常规算术转换的操作中。 - Vlad from Moscow
2
你可能想阅读关于C++中的标准转换的内容(http://en.cppreference.com/w/cpp/language/implicit_cast)。还有关于C语言的内容(http://en.cppreference.com/w/c/language/conversion)。 - Some programmer dude
1
@Patrick B. 关于字面值,它们没有转换。这是浮点字面量的定义。 - Vlad from Moscow
无论如何,您都不能将double传递给模板。而且模板实例化将具有具体的函数签名。 - MSalters
1个回答

9
在C中:
没有后缀的带有.的数字文字,例如3.14,不涉及任何提升。它在其整个生命周期中都是double
如果浮点数作为函数调用的参数,并且被调用的函数没有原型在作用域内,或者该参数对应于作用域内原型中的省略号(...),则浮点数将被提升为双精度。
在以下任何情况下,浮点数都会转换为双精度:
  • 浮点数是函数调用的参数,对应于作用域内类型为double的参数。
  • 二元运算符具有doublefloat作为两个参数类型。适用于此类运算符的运算符是:* / + - < > <= >= == !=
  • 条件运算符的第二个和第三个操作数(以任何顺序)均为doublefloat
  • 浮点数被强制转换为double
  • 浮点数被赋值给double(包括复合赋值)

在C++中,所有上述情况仍然适用,除了关于没有原型的情况(因为C++要求所有函数调用在作用域内都有原型)。
还有一种新情况:标准转换序列,它太复杂了,无法简要概括。但是作为一个例子,这段C++代码包含从floatdouble的隐式转换:
class T { public: T(double dummy) {} };
void foo(T); 
foo(3.14f); // Conversion sequence: float->double->T

我不确定这是否是C++的详尽列表。

1
C++没有“无原型函数”(即在C++中,void foo()是一个没有参数的函数)。除此之外,这些情况在C++中也适用。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接