为什么“0f”不是“0f”?在 C++ 中被视为浮点文字?

发布于 2024-09-28 08:00:04 字数 267 浏览 9 评论 0原文

为什么 0f 在 C++ 中不被视为浮点文字?

#include <iostream>

using namespace std;

int main(){
  cout << 0f << endl;

  return 0;
}

编译上面的内容给了我

C2509(语法错误:“号码后缀错误”)

Why isn't 0f treated as a floating point literal in C++?

#include <iostream>

using namespace std;

int main(){
  cout << 0f << endl;

  return 0;
}

Compiling the above gives me

C2509 (syntax error: 'bad suffix on number')

using VS2008.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

地狱即天堂 2024-10-05 08:00:04

如果这个设计决策有明确说明的原因,那么它将在 C99“基本原理”文档中(C++ 从 C 中逐字复制所有这些内容,而无需重新考虑)。但没有。这是关于“f”后缀的所有内容:

§6.4.4.2 浮点常量

与现有实践一致,浮点常量被定义为具有
输入double。由于 C89 允许表达式仅包含 float 操作数
float 算术而不是 double 执行,这是一种方法
表达显式的 float 常量是可取的。 long double 类型
提出了类似的问题。

添加了 FL 后缀来传达类型信息
浮点常量,与长整数的 L 后缀非常相似。默认
为了与之前的实践兼容,浮点常量的类型保留为 double。
小写的 fl 也可以作为后缀。

不过,有一个隐含的原因。请注意措辞:“添加了 ... 后缀以通过浮动常量传达类型信息。”该标准的作者认为,当您到达后缀时,数字常量已经明确地要么是整数,要么是浮点。后缀仅用于类别内的额外特殊性,它不能将数字从一个类别翻转到另一个类别。这得到了实际语法 (C99 §6.4.4) 的支持,其中首先将数字常量定义为整型常量或浮点常量,然后定义单独的类每个的后缀。

If there was an explicitly stated reason for this design decision, it would be in the C99 "Rationale" document (C++ copied all this stuff verbatim from C without reconsidering it). But there isn't. This is everything that's said about the 'f' suffix:

§6.4.4.2 Floating constants

Consistent with existing practice, a floating-point constant is defined to have
type double. Since C89 allows expressions that contain only float operands
to be performed in float arithmetic rather than double, a method of
expressing explicit float constants is desirable. The long double type
raises similar issues.

The F and L suffixes have been added to convey type information with
floating constants, much like the L suffix does for long integers. The default
type of floating constants remains double for compatibility with prior practice.
Lower-case f and l are also allowed as suffixes.

There is an implied reason, though. Note the wording: "the ... suffixes have been added to convey type information with floating constants." The authors of the standard were thinking of numeric constants as already being unambiguously either integer or floating point by the time you get to the suffix. The suffix is only for extra specificity within the category, it can't flip a number from one category to another. This is backed up by the actual grammar (C99 §6.4.4) which first defines numeric constants as being either integer-constants or floating-constants, and then defines separate classes of suffixes for each.

一念一轮回 2024-10-05 08:00:04

假设 C++ 用于浮点常量的语法与 C 相同(我认为这是正确的),我们有:

一些快捷方式的定义取自 ANSI C 语法

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)*

现在是 fF您会看到浮点的末尾是在上面的 FS 中定义的。

现在让我们看看识别有效浮点常量的语法:

{D}+{E}{FS}?        
{D}*"."{D}+({E})?{FS}?  
{D}+"."{D}*({E})?{FS}?  

现在,如果您仔细观察,没有任何规则可以识别 0f

使用规则 1,我们可以得到 0e0f

使用规则 2,我们可以得到 .0f0.0f

使用规则 3,我们可以得到 0.f 或 0.0f

在您的情况下实际发生的是 0f0 将被词法分析器作为整数常量 Df 将作为 FS 令牌使用。现在,当解析发现 D 后跟 FS 且没有匹配规则时,它会输出错误:

error: invalid suffix "f" on integer constant

Assuming grammar used by C++ for floating point constants is same as that for C (which I think is true), we have:

Definitions of some shortcuts taken from 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)*

Now the f or F you see at the end of the floating points is in defined in FS above.

Now lets see the grammar to recognize valid floating point constants:

{D}+{E}{FS}?        
{D}*"."{D}+({E})?{FS}?  
{D}+"."{D}*({E})?{FS}?  

Now if you see carefully there is no rule that would identify 0f.

Using rule1 we can have 0e0f

Using rule2 we can have .0f or 0.0f

Using rule3 we can have 0.f or 0.0f

What actually happen in your case is the 0 of 0f will be consumed by the lexical analyzer as an integer constant D and the f will be consumed as the FS token. Now when the parse sees a D followed by FS for which there is no matching rule, it spits out the error:

error: invalid suffix "f" on integer constant
安静 2024-10-05 08:00:04

因为0是整数常量。

编辑:codepad.org 给出的错误消息(假设是 g++)可能更容易理解一点。 “错误:整数常量上的后缀“f”无效”。 “0.f”会起作用,因为 0. (或 0.0,同样的东西)是十进制常量,并且要求十进制常量为浮点比要求整数常量为浮点更有意义:)

Because the 0 is an integer constant.

edit: The error message given by codepad.org (assume g++) may be a little easier to understand. "error: invalid suffix "f" on integer constant". A "0.f" will work because 0. (or 0.0, same thing) is a decimal constant, and asking for a decimal constant to be a float makes more sense than asking for an integer constant to be a float :)

伪心 2024-10-05 08:00:04

因为你需要0.0f

Because you need 0.0f.

悲凉≈ 2024-10-05 08:00:04

这里有一个“因为”:如果带有 f 后缀的 int 常量自动转换为 float,则 0x0f 会产生歧义。

Here's a 'because' for you: if an int constant with an f suffix was automatically converted to float, then 0x0f would be ambiguous.

相思故 2024-10-05 08:00:04

这不一定是唯一的原因,但 lL 后缀可以应用于整数文字或浮点文字。 42L 的类型为 long int42.0L 的类型为 long double

带有 L 后缀的数字文字必须消除歧义才能确定它是整数还是浮点数。允许 F 后缀本身来确定文字的类型将是不一致的,并且可能会造成混乱。这也将使在该语言的未来版本中添加新后缀变得更加困难。

This isn't necessarily the only reason, but an l or L suffix can be applied to an integer literal or to a floating-point literal. 42L is of type long int; 42.0L is of type long double.

A numeric literal with an L suffix must be disambiguated to determine whether it's integer or floating-point. Allowing an F suffix by itself to determine the type of a literal would be inconsistent and potentially confusing. It would also make it more difficult to add new suffixes in future versions of the language.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文