Why does taking a function pointer to `operator new` compile in C++14, but not in C++17?
Asked Answered
R

1

13

Consider the following code (godbolt link):

#include <cstdio>

int main() {
    auto foo = operator new;
    void* mem = foo(1);
    printf("%p", mem);
}

This code compiles on GCC, Clang, and MSVC with the C++ version set to C++ 14, but it fails to compile when using C++ 17 or later. On GCC, it fails with the following error:

error: unable to deduce 'auto' from 'operator new'

I expected the code to either compile or not compile in both versions. What changed in C++ 17 that makes it so that the type of operator new can no longer be deduced?

Runaway answered 28/7, 2023 at 12:44 Comment(4)
In C++14, there was only one operator new function. In C++17, there are two operator new functions — the compiler doesn't know which one you want.Gonocyte
operator new is not an addressable library function so this program has unspecified behaviour and is possibly ill-formed in any C++ standard.Mayor
Just use a lambda function, removes all ambiguity.Gensler
@Vince Great first question on SO! Most new C++ contributors tends to ask silly questions that got massively downvoted, but this one is interesting even for seasoned C++ programmers like me.Monotint
M
15

What changed in C++ 17 that makes it so that the type of operator new can no longer be deduced?

This is P0035R41. It introduces in C++17 a new (pun intended) operator new to allow dynamic memory allocation for over-aligned data.

You can find on cppreference.com the two following operators:

void* operator new  ( std::size_t count );
void* operator new  ( std::size_t count, std::align_val_t al );

This makes auto foo = operator new ambiguous as it could match both operators.

As user n. m. will see y'all on Reddit commented:

operator new is not an addressable library function so this program has unspecified behaviour and is possibly ill-formed in any C++ standard.


1)

Problem statement

To codify widespread existing practice, C++11 added the ability to specify increased alignment (a.k.a. over-alignment) for class types. Unfortunately (but also consistently with existing practice), C++11 did not specify any mechanism by which over-aligned data can be dynamically allocated correctly (i.e. respecting the alignment of the data). For example:

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

In this example, not only is an implementation of C++ not required to allocate properly-aligned memory for the array, for practical purposes it is very nearly required to do the allocation incorrectly. In any event, it is certainly required to perform the allocation by a process that does not take the specified alignment value into account.

This represents a hole in the support for alignment in the language, which really needs to be filled.

Messidor answered 28/7, 2023 at 12:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.