constなオブジェクトへのポインタをdeleteしたときの挙動
以下のコードはコンパイルし,動作します.(Wandboxのg++ 4.9.2,clang 3.5.0にて確認,以下同じ)
#include <new>
int main(){
auto p = new int const(0);
delete p;
}
しかし,delete p;を::operator delete(p);で置き換えた場合にはコンパイルエラーが発生してしまいます.(g++での例,clangでもコンパイルエラー)
prog.cc: In function 'int main()':
prog.cc:4:24: error: invalid conversion from 'const void*' to 'void*' [-fpermissive]
::operator delete(p);
確かにconstなオブジェクトへのポインタは非constなオブジェクトへのポインタには変換できませんし,operator deleteが非constなオブジェクトへのポインタを要求するのは理解できるのですが,ではなぜ最初のdelete式がコンパイル可能であるのかが分かりません.
N3797の§5.3.5.7より,
Otherwise, the delete-expression will not call a deallocation function (3.7.4.2).
とあるので,operator delete
の呼び出しが省略されたのかと考えましたが,以下のコードを実行してみたところ,op delete
が出力されました.(bは無関係なオブジェクトでの呼び出しを避けるために使用しています)
#include <new>
#include <iostream>
bool b = false;
void operator delete(void*) noexcept{
if(b){
std::cout << "op delete" << std::endl;
}
}
int main(){
b = true;
auto p = new int const(0);
delete p;
b = false;
}
この結果はどのように解釈すれば良いのでしょうか.