1

gcc-4.8 (Coliru 経由) および Visual Studio 2013 RC で次のプログラムをテストしました。

#include <iostream>
#include <functional>

using namespace std;

struct foo {
    void bar() {
        cout << "this = " << this << endl;
    }
};

int main() {
    try {
        foo *ptr = nullptr;
        function<void ()> fun = bind(&foo::bar, *ptr);
        fun();
    } catch (const bad_function_call &e) {
        // never reached
        cout << "bad_function_call thrown: " << e.what() << endl;
    } 

    cin.get();
}

ここで nullptr を逆参照することで未定義の動作を引き起こしていることは理解していますが、コードの出力はわかりません。私の理解では、これは bad_function_call を引き起こす必要があります (これは、私が推測したことから、この std::function を呼び出すときにスローされる必要があるためです) か、少なくとも「this = 0」を出力する必要があります。

そうではありません。出力は、「this =」であり、その後に、テストした両方のコンパイラで nullptr ではないポインターが続きます。ただし、アクセスするとセグメンテーション違反が発生します。

これを指定する標準の条項はありますか? それとも、実装定義の「未定義の動作」ですか?

編集:追加として:次のコードは、私のマシンで「this = 0」を出力します:

foo *ptr = nullptr;
ptr->bar();
4

2 に答える 2

1

何が起こるかというbindと、引数のコピーが格納されます。引数は型foo( を渡している*ptrため) であるため、コピーが作成されます。もちろん、コピーはソースとして無効な引数を取得しますが、それは使用されていないため、これは機能しているようです。その結果、 の新しいインスタンスがfooバインドされたオブジェクト内に格納され、これが表示されるアドレスになります。

セグメンテーション違反が見られると言うとき、ここで示した例ではなく、実際のコードを参照していますよね? あなたの実際のコードでは、copy-ctor が機能しているように見えますが、(おそらく無効な) メンバーにアクセスするとセグメンテーション違反を引き起こすインスタンスを作成します。

于 2013-10-06T15:19:48.650 に答える
0

「未定」は未定という意味です。未定義の動作がある場合に何が起こるかについての推論は、コンパイラがその動作を文書化しない限り無駄です。

于 2013-10-06T15:26:25.267 に答える