Vla*_*cow 9 c++ floating-point syntax pseudo-destructor c++17
考虑以下演示程序。
#include <iostream>
int main()
{
typedef float T;
0.f.T::~T();
}
Run Code Online (Sandbox Code Playgroud)
该程序由Microsoft Visual Studio Community 2019.
但是clang并gcc发出这样的错误
prog.cc:7:5: error: unable to find numeric literal operator 'operator""f.T'
7 | 0.f.T::~T();
| ^~~~~
Run Code Online (Sandbox Code Playgroud)
如果像这样写表达式,( 0.f ).T::~T()那么所有三个编译器都会编译程序。
所以出现了一个问题:这个记录在0.f.T::~T()语法上有效吗?如果不是,那么什么句法规则被破坏了?
数字标记的解析非常粗糙,并且允许许多实际上不是有效数字的东西。在 C++98 中,“预处理数字”的语法(可在 [lex.ppnumber] 中找到)是
pp-number:
digit
. digit
pp-number digit
pp-number nondigit
pp-number e sign
pp-number E sign
pp-number .
Run Code Online (Sandbox Code Playgroud)
这里,“非数字”是除数字之外可在标识符中使用的任何字符,并且“符号”是+或-。后来的标准将扩展定义以允许单引号 (C++14) 和 p-、p+、P-、P+ (C++17) 形式的序列。
结果是,在该标准的任何版本中,虽然预处理数字需要以数字或句点后跟数字开头,但之后可以跟随任意数字、字母和句点序列。使用最大咀嚼规则,即使不是有效的数字标记,也0.f.T::~T();需要将其标记为。0.f.T :: ~ T ( ) ;0.f.T
因此,该代码在语法上无效。