为什么在 C++ 中不0f
被视为浮点文字?
#include <iostream>
using namespace std;
int main(){
cout << 0f << endl;
return 0;
}
编译上面给了我
C2509(语法错误:'数字后缀错误')
使用VS2008。
为什么在 C++ 中不0f
被视为浮点文字?
#include <iostream>
using namespace std;
int main(){
cout << 0f << endl;
return 0;
}
编译上面给了我
C2509(语法错误:'数字后缀错误')
使用VS2008。
如果这个设计决定有明确说明的原因,那将是在 C99“基本原理”文档中(C++ 从 C 中逐字复制了所有这些东西,而没有重新考虑它)。但是没有。这就是关于“f”后缀的所有内容:
§6.4.4.2 浮动常量
与现有实践一致,浮点常量被定义为具有 type
double
。由于 C89 允许仅包含float
操作数的表达式以float
算术而不是执行double
,因此需要一种表达显式float
常量的方法。该long double
类型引发了类似的问题。添加了
F
和L
后缀来传达带有浮动常量的类型信息,就像L
长整数的后缀一样。为了与先前的做法兼容,浮动常量的默认类型保持为 double。小写f
并且l
也允许作为后缀。
不过,有一个隐含的原因。请注意措辞:“已添加 ... 后缀以使用浮动常量传达类型信息。” 该标准的作者认为数字常量在您到达后缀时已经明确地是整数或浮点数。后缀仅用于类别内的额外特异性,它不能将数字从一个类别翻转到另一个类别。这得到了实际语法(C99 §6.4.4)的支持,该语法首先将数字常量定义为整数常量或浮点常量,然后为每个定义单独的后缀类。
假设 C++ 用于浮点常量的语法与 C 的语法相同(我认为这是真的),我们有:
一些快捷方式的定义取自ANSI C grammar
D [0-9]
L [a-zA-Z_]
H [a-fA-F0-9]
E [Ee][+-]?{D}+
FS (f|F|l|L)
IS (u|U|l|L)*
现在,您在浮点末尾看到的f
orF
已在FS
上面定义。
现在让我们看看识别有效浮点常量的语法:
{D}+{E}{FS}?
{D}*"."{D}+({E})?{FS}?
{D}+"."{D}*({E})?{FS}?
现在,如果您仔细观察,没有任何规则可以识别0f
。
使用 rule1 我们可以有0e0f
使用 rule2 我们可以拥有.0f
或0.0f
使用 rule3 我们可以拥有0.f
或0.0f
在您的情况下,实际发生的情况是0
of0f
将被词法分析器作为整数常量使用D
,而 thef
将作为FS
令牌使用。现在,当解析看到 aD
后跟FS
没有匹配规则时,它会吐出错误:
error: invalid suffix "f" on integer constant
因为 0 是一个整数常量。
编辑:codepad.org(假设 g++)给出的错误信息可能更容易理解一些。“错误:整数常量上的后缀“f”无效”。“0.f”会起作用,因为 0.(或 0.0,同样的东西)是一个十进制常量,并且要求一个十进制常量是一个浮点数比要求一个整数常量是一个浮点数更有意义 :)
因为你需要0.0f
.
这对您来说是一个“因为”:如果int
带有f
后缀的常量自动转换为float
,那么0x0f
将是模棱两可的。
这不一定是唯一的原因,但可以将l
orL
后缀应用于整数文字或浮点文字。42L
是类型long int
;42.0L
是类型long double
。
必须消除带后缀的数字文字的L
歧义,以确定它是整数还是浮点数。允许F
后缀本身来确定文字的类型将是不一致的并且可能会造成混淆。这也将使在该语言的未来版本中添加新后缀变得更加困难。