4

古いコード ベースで発見したものを見ていますが、かなり混乱しています。

関数定義は次のとおりです。

void vUpdateSequenceDetailsAndIncrement(
            const CallEvent& roCPEvent,
            const CallInfo& roCallInfo,
            BOOL bCreationEvent);

ここでは、次のように呼ばれています。

vUpdateSequenceDetailsAndIncrement(roCPEvent, NULL, FALSE);

ここでは、 NULLが参照パラメータに直接渡されていますroCallInfo。この関数は最終的に以下を呼び出します。

vTimeChange(*pSeqDetails, roCPEvent, roCallInfo);

これは次のように定義されています。

void vTimeChange(const SequenceDetails& roSequenceDetails,
        const CallEvent& roCPEvent,
        const CallInfo& roCallInfo)

再度、NULL の可能性がある値を に渡しますroCallInfo。参照として NULL を渡せないと思っていたのですが?VC++ 4.x に何らかの問題があり、この種のコードを問題なく使用できるかどうかを知っている人はいますか? NULL を参照として渡すことができる場合、vTimeChange で次のようなことが起こるとどうなりますか。

roCallInfo.getCallStartTime(); 

それは私がやったのと同じように NULL の逆参照ではありませんか

CallInfo * info = NULL;
info->getCallStartTime();

? とにかくそこにガードを置き、不要であればコンパイラーにそれを削除させますが、これがどのように起こっているのかを知りたいです!

ありがとう。

4

3 に答える 3

8

VC 4.2 で NULL がどのように定義されているかによって異なります。

それだけなら

#define NULL 0 

次に、実際にこれを内部で取得しています。

vUpdateSequenceDetailsAndIncrement(roCPEvent, CallInfo(0), FALSE);

CallInfo 型の一時変数の参照が関数に渡されます (CallInfo に互換性のある ctor がある場合)。

于 2011-09-07T17:23:23.027 に答える
5

NULL参考にならないかな?

有効な参照を null にすることはできませんが、無効な参照を null にすることはできます。
ここにあるのは無効な参照です。

この場合に見られるように、参照を null にできないという事実は、参照がポインターよりも何らかの形で安全であることを意味するわけではありません。プログラムが無効な参照につながる可能性がある多くの方法があります。あなたのコードはその一例です。

参照ウィキペディア: aを開始できる
事実上の方法もあります。参照は通常、基になるポインターとして実装されるため、ポインター逆参照式での参照の初期化は、通常、ポインターから参照の基になるポインターへの単純な代入としてコンパイラによって実装されます。したがって、ポインタまたはメモリ内の無効な場所を指すポインタがある場合、事実上、NULL または無効な場所を指す参照を持つことになります。C++ の純粋主義者は、技術的には、NULL または無効なポインターの逆参照はいずれにせよ未定義の動作につながると主張するため、これは、参照を null にすることも、メモリ内の任意の場所を指すこともできないという上記の主張に違反しません。referenceinvalidNULL. ただし、これは、この場合、基礎となる実装が単に「割り当て」を実行し、関連するメモリ位置へのアクセスがないという事実を無視しているため、この参照の初期化は通常問題を引き起こさず、プログラマは注意する必要があります実際のプログラムでの事実上の「無効な」参照の可能性。

無効な参照 を使用すると、roSequenceDetails最終的に未定義の動作が発生します。

于 2011-09-07T17:22:03.507 に答える
0

が nullの場合、式*pSeqDetailsは未定義の動作になります。pSeqDetails何でも起れる。ほとんどの実装では、特定のチェックは行われません。オブジェクトを実際に必要とする何かを実行するまで、コードは機能しているように見えますが、その後は失敗します。ただし、実装により、すぐに失敗する可能性があります。

于 2011-09-07T17:18:03.243 に答える