Why isn't "0f" treated as a floating point literal in C++?
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.
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 onlyfloat
operands to be performed infloat
arithmetic rather thandouble
, a method of expressing explicitfloat
constants is desirable. Thelong double
type raises similar issues.The
F
andL
suffixes have been added to convey type information with floating constants, much like theL
suffix does for long integers. The default type of floating constants remains double for compatibility with prior practice. Lower-casef
andl
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.
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
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 :)
Because you need 0.0f
.
Here's a 'because' for you: if an int
constant with an f
suffix was automatically converted to float
, then 0x0f
would be ambiguous.
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.
精彩评论