2

私が書いていなかった古いコードを調べていると、このようなものに気づきました(簡略化)

//switch case on a msg received from a queue,...
//... get_function returns msgtype and ptr
switch(msgtype)
//...
default:
{
    MYLOGGER<< "Unknown message" << (*ptr)->some_member_var <<"\r\n";
}

だから私はそれをに変更しようと思った

        default:
{
    MYLOGGER<< "Unknown message...\r\n";
    MYLOGGER<< "..." << (*ptr)->some_member_var << "\r\n";
}

ptrがジャンクの場合、ロギングが始まる前にクラッシュするのを恐れますか?この例では私は厳密ですか?また、一般に、エラーをログに記録するときに間接参照を行わないようにする必要があります。

編集:MYLOGGERに関しては、これで終わるマクロです:オーバーロードされた演算子<<を持つロガークラスは、dtrorでostream flush()を実行するため、endlは必要ありません。

4

4 に答える 4

2

現在のコードがクラッシュする場合は、新しいコードもクラッシュします。より良い解決策は、逆参照する前に単に nullptr をチェックし、その場合は特別なメッセージを出力することです。

if(ptr == nullptr)
    MYLOGGER<<"invalid null message\r\n";;
else
    MYLOGGER<< "Unknown message " << (*ptr)->some_member_var <<"\r\n";

(コメントによると)operator<<がすでにフラッシュを実行していることを考えると、これは可能な限り安全であり、クラッシュが発生した場合でも(おそらくptrが無効であるがnullptrではない場合)、おそらくログの「不明なメッセージ」を参照してください。

于 2012-12-05T10:13:37.087 に答える
2

私は、Chris Lattner による「すべての C プログラマーが未定義の動作について知っておくべきこと」 (コンパイラーの驚きについて話すのに、コンパイラーのライターよりも優れている人は誰ですか?) に任せます。

TL;DR バージョンは次のとおりです。未定義の場合、コンパイラの最適化のために一時的な安全性はありません。したがって、提示した 2 つのバージョンは厳密に同等です。

于 2012-12-05T10:21:05.370 に答える
1

メッセージが何であるかわからない場合は、その内容を解釈しようとするべきではありません。それ自体の値をログに記録することはできますが、ptrそれがどこを指しているのか本当にわからないので、それを無視しないでください。

于 2012-12-05T10:11:16.947 に答える
0

ロガーは非同期で動作するか、ログを非同期で永続化する可能性があります。その場合、2 番目のコードは最初のコードよりも役に立ちません。
とにかく、チェックされていないポインターへのアクセスは未定義の動作であり、この場合、不明なメッセージが受信されたためにクラッシュする可能性があるため、少し厳しいようです。

于 2012-12-05T10:13:01.657 に答える