c++ - 为浮点常量调用伪析构函数的有效语法
问题描述
考虑以下演示程序。
#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) 形式的序列。
结果是,在任何版本的标准中,预处理数字都需要以数字或句点后跟数字开头,之后可以是任意的数字、字母和句点序列。使用最大咀嚼规则,即使不是有效的数字标记,0.f.T::~T();
也需要将其标记为。0.f.T :: ~ T ( ) ;
0.f.T
因此,代码在语法上无效。
推荐阅读
- docker - 在 Ubuntu 上执行 service docker start 时未正确观察到单元 docker.service 加载
- python - Python 会在每个循环中执行我的方法吗?
- tensorflow - 在 Python 3.7 中使用 Dropout 函数 (Keras) 时如何解决“UnboundLocalError”
- c++ - 在迭代期间删除向量的唯一元素?
- c++ - Python C++ api:如何访问公共类属性?
- visual-studio - 在 Visual Studio 2015 中为调试模式运行 iisexpress 32 位而不是 64 位
- reactjs - 唯一地折叠每个按钮,而不是一次全部折叠
- sql - oracle 触发器和 json_value
- php - 如何在 PHP 类函数中设置变量
- unix - 如何为特定文件的字数添加前缀零以使总数为 8 位并将输出打印到文件