3

次のコードは、nullptrポインターと参照をいじっています。

#include <cstdio>

void printRefAddr(int &ref) {
    printf("printAddr %p\n", &ref);
}

int main() {    
    int *ip = nullptr;
    int &ir = *ip;

    // 1. get address of nullptr reference
    printf("ip=%p &ir=%p\n", ip, &ir);

    // 2. dereference a nullptr pointer and pass it as reference
    printRefAddr(*ip);

    // 3. pass nullptr reference
    printRefAddr(ir);

    return 0;
}

質問: C++ 標準では、コメント付きステートメント 1..3 は有効なコードですか、それとも未定義の動作ですか?

これは、異なるバージョンの C++ と同じですか、それとも異なりますか (古いバージョンではもちろん、キーワード0の代わりにリテラルが使用されます)。nullptr

おまけの質問: 既知のコンパイラ/最適化オプションはありますか?実際に上記のコードが予期しないことやクラッシュを引き起こす可能性がありますか? たとえば、nullptrから参照引数を渡すことを含め、参照が初期化されるすべての場所で暗黙的なアサーションを生成するコンパイラのフラグはあり*ptrますか?


好奇心旺盛で、予期しないものがない場合の出力例:

ip=(nil) &ir=(nil)
printAddr (nil)
printAddr (nil)
4

2 に答える 2

6

// 2. dereference a nullptr pointer and pass it as reference

null ポインターの逆参照はUndefined Behaviorであるため、それを参照として渡すか値で渡すかに関係なく、実際には、それを逆参照して UB を呼び出したということです。つまり、その時点からすべての賭けがオフになります。

ここで既に UB を呼び出しています。

int &ir = *ip; //ip is null, you cannot deref it without invoking UB.
于 2013-04-23T08:09:11.303 に答える
1

irは単なる影であるため*ip、それ自体で未定義の動作が発生することはありません。

未定義の動作は、 を指すポインターを使用していますnullptr_t。を使用するという意味*ipです。したがって

int &ir = *ip;
          ^^^

UB を引き起こします。

于 2013-04-23T08:09:40.577 に答える