江添とボレロ村上の京都C++勉強会は終わってしまったが、C++03とC++11の違いシリーズは続ける。
変更:operator newとoperator deleteの違い
C++11では、単体確保のためのoperator newとoperator deleteは、その他の確保関数、解放関数の基本的な関数として、呼ばれるようになった。
この変更の結果、以下のコード
#include <cstdlib>
#include <iostream>
#include <new>
void * operator new( std::size_t size )
{
std::cout << "allocated" << '\n' ;
return std::malloc( size ) ;
}
void operator delete ( void * ptr ) noexcept
{
std::cout << "deallocated" << '\n' ;
std::free( ptr ) ;
}
int main()
{
int * ptr = new int[3] ;
delete[] ptr ;
}
これを実行した結果は、
allocated deallocated
となることが、C++11では保証されている。C++03では保証されていない。
つまり、C++11では、デフォルトの実装の配列型の確保関数、解放関数に、単数形のものが、使われることが保証されるようになったということだ。
変更:operator newがstd::bad_alloc以外の例外も投げるかもしれないようになった
C++03では、std::operator newには、動的例外指定、throw( std::bad_alloc ) が指定されていた。C++11では、動的例外指定は廃止予定になり、その意味も、単に例外を投げる可能性のある関数程度のものになったので、std::operator newが、std::bad_alloc以外の型を例外として投げる可能性が、規格上出てきた。そのための違い。
次回に続く。
> 変更:std::operator newがstd::bad_alloc以外の例外も投げるかもしれないようになった
ReplyDeleteそんなことは無いですよ。 N3797 18.6.1.1 [new.delete.single] p3
> Required behavior: Return a non-null pointer to suitably aligned
> storage (3.7.4), or else throw a bad_alloc exception.
std::operator newではなく、普通のユーザー定義のoperator newでした。
ReplyDelete> std::operator newではなく、普通のユーザー定義のoperator newでした。
ReplyDeletestd::operator new というものはありません。ライブラリ提供のデフォルト版もグローバル名前空間にあります。( operator new がグローバル以外の名前空間から探索されることはありません)
「普通のユーザー定義のoperator new」がユーザーが置き換え版として定義したものを指すのであれば、そちらも同じ "Required behavior" に従う必要がある(さもなければ未定義の結果を生じる)とされています。 17.6.4.8 [res.on.functions] p2
> In particular, the effects are undefined in the following cases:
> - for replacement functions (18.6.1), if the installed replacement
> function does not implement the semantics of the applicable Required
> behavior: paragraph.
独自の引数を追加したものやクラスのメンバである operator new が投げる例外の種類に規定は無いようですが、それは C++03 でも同じです。