考虑以下演示程序。
#include <iostream>
int main()
{
typedef float T;
0.f.T::~T();
}
该程序由
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();
| ^~~~~
如果要编写像
( 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 .
在这里,“非数字”是可以在标识符中使用的任何字符,除了数字以外,“符号”也可以是+或-。后来的标准将扩展定义,以允许使用单引号(C++ 14)和格式为p-,p +,P-,P +的序列(C++ 17)。
结果是,在该标准的任何版本中,都要求预处理数字以数字或以句点开头的数字开头,之后可以是数字,字母和句点的任意序列。使用最大munch规则,即使
0.f.T::~T();
不是有效的数字 token ,也需要将0.f.T :: ~ T ( ) ;
标记为0.f.T
。因此,该代码在语法上不是,而是。
关于c++ - 为浮点常量调用伪析构函数的有效语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61278180/