N3778 [1] introduced [
expr.new] 5.3.4p20 to C++11:
> A declaration of a placement deallocation function matches the
> declaration of a placement allocation function if it has the same
> number of parameters and, after parameter transformations (8.3.5),
> all parameter types except the first are identical. Any non-placement
> deallocation function matches a non-placement allocation function. If
> the lookup finds a single matching deallocation function, that
> function will be called; otherwise, no deallocation function will be
> called. If the lookup finds the two-parameter form of a usual
> deallocation function (3.7.4.2) and that function, considered as a
> placement deallocation function, would have been selected as a match
> for the allocation function, the program is ill-formed. [ Example:
> struct S {
> // Placement allocation function:
> static void* operator new(std::size_t, std::size_t);
> // Usual (non-placement) deallocation function:
> static void operator delete(void*, std::size_t);
> };
>
> S* p = new (0) S; // ill-formed: non-placement deallocation
function matches
> // placement allocation function
> — end example ]
This is a breaking change. The example code compiles successfully as
C++03, but errors in C++11 using Clang 3.5.
$ cat t.cpp
#include <cstddef>
struct S {
void* operator new(std::size_t, std::size_t);
void operator delete(void*, std::size_t);
};
S* p = new (0) S;
$ clang++ -c -std=c++03 t.cpp
<no error>
$ clang++ -c -std=c++11 t.cpp
t.cpp:8:8: error: 'new' expression with placement arguments refers to
non-placement 'operator delete'
S* p = new (0) S;
^ ~
t.cpp:5:10: note: 'operator delete' declared here
void operator delete(void*, std::size_t);
^
1 error generated.
Recent gcc releases do not appear to enforce 5.3.4p20. I tried
compiling the test with gcc 4.8 and a branch of 4.10, both with
-std=c++11, and both succeeded.
I don't see any mention of this incompatibility under C++11 [diff.cpp03]
C.2, nor have I found a DR for it.
It isn't clear to me why the rule was added. I presume this is an
intentional change that probably should have been documented in C.2.
Anyone know more about this?
Tom.
[1]:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3778.html