为什么将函数指针指向 `operator new` 在 C++14 中可以编译,但在 C++17 中却不能编译?

问题描述 投票:0回答:1

考虑以下代码(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++ c++17 c++14 operator-overloading auto
1个回答
12
投票

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 上看到你们评论:

operator new
不是一个可寻址库函数,因此该程序具有未指定的行为,并且在任何 C++ 标准中都可能格式错误。


1)

问题陈述

为了编纂广泛的现有实践,C++11 添加了为类类型指定增强对齐(也称为过度对齐)的功能。不幸的是(但也与现有实践一致),C++11 没有指定任何可以动态正确分配过度对齐的数据的机制(即尊重数据的对齐)。例如:

class alignas(16) float4 {
  float f[4];
};
float4 *p = new float4[1000];

在此示例中,C++ 的实现不仅不需要为数组分配正确对齐的内存,而且出于实际目的,几乎需要错误地进行分配。无论如何,肯定需要通过不考虑指定对齐值的进程来执行分配。

这代表了语言中对对齐的支持存在一个漏洞,确实需要填补。

© www.soinside.com 2019 - 2024. All rights reserved.