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

C++ 我的初始值设定项列表中的小错误会导致无法形容的痛苦,c++,gcc,g++,compiler-warnings,C++,Gcc,G++,Compiler Warnings,因此,我刚刚完成了一个大型服务器应用程序长达数小时的艰苦调试。这个错误最终归结为构造器中一个几乎不明显的输入错误。基本上是这样的: template <class T> class request_handler { public: request_handler(T& request, Log& error_log) : m_request(m_request), m_error_log(error_log) {

因此,我刚刚完成了一个大型服务器应用程序长达数小时的艰苦调试。这个错误最终归结为构造器中一个几乎不明显的输入错误。基本上是这样的:

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 ... */
     }

    ...
};
…它将发出警告:
警告:“x”在此函数中未初始化使用[-Wuninitialized]


那么,当我将
m_request
分配给自身时,为什么编译器没有警告我:实际上是将未初始化的引用分配给自身?这会让我省去几个小时的烦恼

要追踪的讨厌的bug。事实证明,您甚至不需要模板就可以在这个问题上默默失败。这样就可以了:

class C {
        int a, b;
public:
        C(int t, int z) : a(a), b(z) { };
};
使用
-Wuninitialized
发出警告

对gcc的人来说是个好消息:根据gnu的bugzilla

更新

在gcc 4.7.0中,添加
-Wself init
以获得此警告(验证人):

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
中引用的是参数,而不是成员。当然,对于引用等简单类型来说,这并不重要,但我不建议将其用于类。

您是否在编译时启用了完全优化(-O3)?编译器只有在实际执行数据流分析时才会注意到其中一些错误。也可以考虑删除My前缀。代码>foo(T bar):bar(bar)定义得非常好。起初我是通过优化编译的。但是在调试时,我使用
-g3
标志进行编译,以便使用调试器。即使是<代码> G3标志,它也没有发出任何警告。我不希望代码> -G3/COM>引起这个警告,它所做的只是转储您的符号。我相信“小键入导致无法形容的痛苦”是C++的官方格言。奇怪的是,我没有看到提到成员引用的bug文档,但可能修复程序处理这两种情况的方式是相同的。我的系统上的GCC
GCC版本4.7.0 20120505(prerelease)(GCC)
似乎没有报告错误。另一方面,clang正确地报告它:
clang++-Wall-ctst.cctst.cc:4:29:警告:当在这里使用[-Wuninitialized]c(intt,intz):a(a),b(z){};^生成1个警告。
@sbellef,您使用了-Wself init吗?没有,我只使用了
-Wall
。现在如果我添加
-Winit self
我得到:
tst.cc:在构造函数'C::C(int,int)':tst.cc:4:9:警告:'C::a'是用自身初始化的[-Wuninitialized]
,这就是为什么它应该是
T const&request
-你只需要参数来初始化
这个->请求
,你不需要修改它。如果您的用例更复杂,那么我建议您不要这样做。但是,如果您在简单的情况下始终使用此模式,那么额外的好处是该模式变得可识别。“哦,那个参数
Foo
只是用来初始化
Foo
。我正在查看
Bar
,所以我不需要关心
Foo
template <class T>
request_handler(T& request, Log& error_log) 
 : request(request), error_log(error_log)
{ 
  /*... some code ... */
}