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()那么所有三个编译器都会编译程序。

所以出现了一个问题:这个记录在0.f.T::~T()语法上是否有效?如果不是,那么什么语法规则被打破了?

4

2 回答 2

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

因此,代码在语法上无效

于 2020-04-18T01:42:05.300 回答
1

用户定义的文字后缀ud-suffix是一个标识符标识符是一系列字母(包括一些非 ASCII 字符)、下划线和不以数字开头的数字。不包括句点字符。

因此这是一个编译器错误,因为它将非标识符序列f.T视为标识符。

0.是一个小数常数,后面可以跟一个可选的指数,然后是ud-suffix(用于用户定义的文字)或浮点后缀(其中之一fFlL)。f也可以被认为是ud-suffx ,但由于它匹配另一个文字类型,它应该是那个而不是 UDL。ud-suffix在语法中定义为标识符。

于 2020-04-17T18:34:17.477 回答