首页 > 解决方案 > 为浮点常量调用伪析构函数的有效语法

问题描述

考虑以下演示程序。

#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()语法上是否有效?如果不是,那么什么语法规则被打破了?

标签: c++syntaxfloating-pointc++17pseudo-destructor

解决方案


数字标记的解析非常粗糙,并且允许许多实际上不是有效数字的东西。在 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

因此,代码在语法上无效


推荐阅读