考虑以下代码(godbolt 链接):
#include <cstdio>
int main() {
auto foo = operator new;
void* mem = foo(1);
printf("%p", mem);
}
此代码在 C++ 版本设置为 C++ 14 的 GCC、Clang 和 MSVC 上编译,但在使用 C++ 17 或更高版本时无法编译。在 GCC 上,它失败并出现以下错误:
error: unable to deduce 'auto' from 'operator new'
我预计代码在两个版本中要么编译,要么不编译。 C++ 17 中发生了什么变化,导致无法再推断出
operator new
的类型?
C++ 17 中发生了什么变化,导致无法再推导 new 运算符的类型?
这是P0035R41。它在 C++17 中引入了一个新的(双关语)
operator new
,以允许对过度对齐的数据进行动态内存分配。
您可以在 cppreference.com 上找到两个以下运算符:
void* operator new ( std::size_t count );
void* operator new ( std::size_t count, std::align_val_t al );
这使得
auto foo = operator new
不明确,因为它可以匹配两个运算符。
作为用户 n。米。会在 Reddit 上看到你们评论:
不是一个可寻址库函数,因此该程序具有未指定的行为,并且在任何 C++ 标准中都可能格式错误。operator new
1)
问题陈述
为了编纂广泛的现有实践,C++11 添加了为类类型指定增强对齐(也称为过度对齐)的功能。不幸的是(但也与现有实践一致),C++11 没有指定任何可以动态正确分配过度对齐的数据的机制(即尊重数据的对齐)。例如:
class alignas(16) float4 { float f[4]; }; float4 *p = new float4[1000];
在此示例中,C++ 的实现不仅不需要为数组分配正确对齐的内存,而且出于实际目的,几乎需要错误地进行分配。无论如何,肯定需要通过不考虑指定对齐值的进程来执行分配。
这代表了语言中对对齐的支持存在一个漏洞,确实需要填补。