2013-12-26

C++03とC++11の違い:言語サポートライブラリ編

江添とボレロ村上の京都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以外の型を例外として投げる可能性が、規格上出てきた。そのための違い。

次回に続く。

3 comments:

Anonymous said...

> 変更:std::operator newがstd::bad_alloc以外の例外も投げるかもしれないようになった

そんなことは無いですよ。 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.

江添亮 said...

std::operator newではなく、普通のユーザー定義のoperator newでした。

Anonymous said...

> std::operator newではなく、普通のユーザー定義のoperator newでした。

std::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 でも同じです。