浮動小数点定数の疑似デストラクターを呼び出す有効な構文


9

次のデモプログラムを検討してください。

#include <iostream>

int main()
{
    typedef float T;

    0.f.T::~T();
}

このプログラムはによってコンパイルされMicrosoft Visual Studio Community 2019ます。

しかしclanggccこのようなエラーを発行します

prog.cc:7:5: error: unable to find numeric literal operator 'operator""f.T'
    7 |     0.f.T::~T();
      |     ^~~~~

このような式を記述する場合、( 0.f ).T::~T()3つのコンパイラすべてがプログラムをコンパイルします。

したがって、疑問が生じ0.f.T::~T()ます。このレコードは構文的に有効ですか?そうでない場合、どの構文規則が違反していますか?


1
間にスペースを入れる0.fと、.T両方のGCCとクラン原因は...これを受け入れるように
クリス・

1
同様に(0.f).T::~T();
cigien

単純なfloat f = 1.0f.t;場合、数値リテラルに関するエラーが発生します。
1201ProgramAlarm

A float組み込み型であり、呼び出すデストラクタがありません。手動でデストラクタを呼び出していますか?配置-新しい領域の外では、それは大きなノーノーでなければなりません。
Jesper Juhl

@JesparJuhlはデストラクタではなく疑似デストラクタです。私はそれが存在することを知りました。タグ情報には例があります(これにはデストラクタbtwへの正当化されていない呼び出しもあります)
idclev 463035818

回答:


3

数値トークンの解析は非常に大雑把であり、実際に有効な数値ではない多くのことを可能にします。C ++ 98では、[lex.ppnumber]にある「前処理番号」の文法は次のとおりです。

pp-number:
    digit
    . digit
    pp-number digit
    pp-number nondigit
    pp-number e sign
    pp-number E sign
    pp-number .

ここで、「非数字」は、数字以外の識別子で使用できる任意の文字であり、「符号」は+または-のいずれかです。後の標準では、定義を拡張して一重引用符(C ++ 14)、およびp-、p +、P-、P +(C ++ 17)の形式のシーケンスを許可します。

要するに、標準のどのバージョンでも、数字またはピリオドの後に数字が続く前処理番号が必要であり、その後に任意の数字、文字、およびピリオドのシーケンスが続く場合があります。最大ムンチ規則を使用すると、は有効な数値トークンではありませんが、0.f.T::~T();としてトークン化する必要があります。0.f.T :: ~ T ( ) ;0.f.T

したがって、コードは構文的に有効ではありません


興味深いことに、実際には[lex.pptoken]にかなりの類似性がある例があります:eel.is/c++draft/lex.pptoken#5
chris

1

ユーザー定義のリテラルサフィックスud-suffix識別子です。識別子は数字で始まっていません(一部の非ASCII文字を含む)の文字、アンダースコア、および数字のシーケンスです。ピリオド文字は含まれません。

したがって、非識別子シーケンスf.Tを識別子として処理しているため、コンパイラのバグです。

0.ある分数定数任意の指数、その後のいずれかが続くことができ、UD-サフィックス(ユーザーのためにリテラル定義)または浮動小数点接尾語(のいずれかfFlL)。f考えることができるUD-suffxとしても、それは別のリテラル型と一致するので、それはそれではなくUDLでなければなりません。UD-サフィックスは識別子として文法で定義されています。


なぜudサフィックスとして解釈されるのですか?
ヴラドモスクワ発

@VladfromMoscow The 0.分数定数です。その後に(指数部分を除く)udサフィックス(ユーザー定義リテラルの場合)または浮動小数点サフィックス(のいずれか)を続けることができますfFlLf考えることができるUD-suffxとしても、それは別のリテラル型と一致するので、それはそれではなくUDLでなければなりません。UD-サフィックスはとして文法で定義された識別子
1201ProgramAlarm

@ 1201ProgramAlarm:fud-suffixとして解釈できます が、識別子にf.T含めることは.できません。しかし、それは...私はコンパイラのバグを言うでしょうが、かなり複雑であることは確かです。
Jarod42
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.