我的初始值设定项列表中的小拼写错误会导致无法形容的痛苦

Small typo in my initializer list causes unspeakable pain

本文关键字:误会 错误 痛苦 我的 列表      更新时间:2023-10-16

所以,我刚刚完成了一个大型服务器应用程序的耗时调试会话。 该错误最终归结为构造函数中几乎不明显的拼写错误。 基本上,它是这样的:

template <class T>
class request_handler
{
    public:
    request_handler(T& request, Log& error_log) 
      : m_request(m_request), m_error_log(error_log)
     { 
       /*... some code ... */
     }
    ...
};

看到错误了吗? 好吧,我没有。 问题是初始值设定项列表中的一个小拼写错误:m_request(m_request)正在为自己分配一个未初始化的引用。 显然,它应该阅读m_request(request).

现在,成员变量 m_request 的类型为 T& 。 那么 - 编译器没有警告我我在这里使用未初始化的变量有什么原因吗?

使用带有 -Wall 标志的 GCC 4.6,如果我说:

int x;
x = x;

。它将发出警告:warning: ‘x’ is used uninitialized in this function [-Wuninitialized]

那么,为什么编译器在我为自己分配m_request时没有警告我:本质上是为自己分配一个未初始化的引用? 这会为我节省数小时的烦恼。

要追踪的烦人错误。事实证明,您甚至不需要模板来默默地失败。这将解决问题:

class C {
        int a, b;
public:
        C(int t, int z) : a(a), b(z) { };
};

叮当用-Wuninitialized警告这一点。

对于 gcc 人来说是个好消息:根据 gnu 的 bugzilla,gcc 4.7.0 已经解决了这个问题。

更新

在 gcc 4.7.0 上,添加-Wself-init以获取此警告(由 sbellef 验证(:

tst.cc:在构造函数 'C::C(int, int(' 中: tst.cc:4:9: 警告: 'C::a' 用自身初始化 [-Wuninitialized]

我喜欢

使用与构造函数参数相同的成员名称的技巧。

template <class T>
request_handler(T& request, Log& error_log) 
 : request(request), error_log(error_log)
{ 
  /*... some code ... */
}

这将始终防止错误。你必须小心,因为在函数体中request引用参数,而不是成员。对于引用等简单类型,这当然无关紧要,但我不建议将其用于类。