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 版本是:当它未定义时,由于编译器优化,没有时间安全性。因此,您提供的两个版本是严格等价的。

于 2012-12-05T10:21:05.370 回答
1

如果您不知道消息是什么,则不应尝试以任何方式解释其内容。你可以记录ptr它自己的值,但你并不真正知道它指向哪里,所以不要尊重它。

于 2012-12-05T10:11:16.947 回答
0

您的记录器可能异步工作,或者使日志异步持久化,在这种情况下,第二个代码不会比第一个更有用。
无论如何,访问未经检查的指针是未定义的行为,在这种情况下,可能会因为收到未知消息而崩溃,这似乎有点苛刻。

于 2012-12-05T10:13:01.657 回答