0f
C++ で浮動小数点リテラルとして扱われないのはなぜですか?
#include <iostream>
using namespace std;
int main(){
cout << 0f << endl;
return 0;
}
上記をコンパイルすると、
C2509 (構文エラー: '番号の接尾辞が正しくありません')
VS2008 を使用しています。
0f
C++ で浮動小数点リテラルとして扱われないのはなぜですか?
#include <iostream>
using namespace std;
int main(){
cout << 0f << endl;
return 0;
}
上記をコンパイルすると、
C2509 (構文エラー: '番号の接尾辞が正しくありません')
VS2008 を使用しています。
この設計上の決定に明確に述べられた理由がある場合、それはC99の「Rationale」ドキュメントにあります(C ++は、これらすべてのものを再考せずにCから逐語的にコピーしました)。しかし、ありません。これは、「f」接尾辞について言われていることのすべてです。
§6.4.4.2浮動定数
既存の慣行と一致して、浮動小数点定数は型を持つように定義されてい
double
ます。C89では、float
オペランドのみを含む式を、float
ではなく算術で実行できるためdouble
、明示的なfloat
定数を表現する方法が望まれます。long double
タイプは同様の問題を引き起こします。
F
接尾辞は、長整数L
の場合と同様に、浮動定数を使用して型情報を伝達するために追加されました。L
浮動定数のデフォルトタイプは、以前の方法との互換性のために2倍のままです。小文字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
orは、上記で定義されています。F
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
、がトークンf
として消費されることです。これで、一致するルールがないa の後に続くがFS
解析で検出されると、エラーが吐き出されます。D
FS
error: invalid suffix "f" on integer constant
0 は整数定数だからです。
編集: codepad.org (g++ を想定) によって表示されるエラー メッセージは、もう少し理解しやすいかもしれません。「エラー: 整数定数の接尾辞 "f" が無効です」. 0. (または 0.0、同じもの) は 10 進定数であり、10 進定数を浮動小数点数にすることは、整数定数を浮動小数点数にすることよりも理にかなっているため、「0.f」は機能します :)
が必要だからです0.0f
。
ここに「理由」があります。接尾辞付きのint
定数f
が自動的に に変換されたfloat
場合、0x0f
あいまいになります。
これが必ずしも唯一の理由ではありませんが、l
orL
接尾辞は整数リテラルまたは浮動小数点リテラルに適用できます。42L
タイプlong int
です。42.0L
タイプlong double
です。
接尾辞付きの数値リテラルは、L
それが整数か浮動小数点かを判別するために、あいまいさを解消する必要があります。サフィックスF
だけでリテラルの型を決定できるようにすると、一貫性がなくなり、混乱を招く可能性があります。また、言語の将来のバージョンで新しい接尾辞を追加することも難しくなります。