我有一个 TestClass 和一个 const& 成员变量。我从各个地方和自己的经验中知道,使用对临时值的引用来初始化这个 const& 是一个坏主意。所以我很惊讶下面的代码可以编译正常(使用 gcc-4.9.1clang-3.5scan-build-3.5 测试)但无法正常运行。

class TestClass {
  public:
    // removing the "reference" would remove the temporary-problem
    const std::string &d;

    TestClass(const std::string &d)
        : d(d) {
        // "d" is a const-ref, cannot be changed at all... if it is assigned some
        // temporary value it is mangled up...
    }
};

int main() {

    // NOTE: the variable "d" is a
    // temporary, whose reference is not valid... what I don't get in the
    // moment: why does no compiler warn me?
    TestClass dut("d");

    // and printing what we got:
    std::cout << "beginning output:\n\n";
    // this will silently abort the program (gcc-4.9.1) or be empty
    // (clang-3.5) -- don't know whats going on here...
    std::cout << "dut.d: '" << dut.d << "'\n";
    std::cout << "\nthats it!\n";

    return 0;
}

为什么两个编译器都没有在编译时警告我?另请参阅此 ideone ,正在进行更多测试。

最佳答案

没有警告,因为没有冒犯:

本地 const 引用延长了变量的生命周期。

该标准在第 8.5.3/5 节 [dcl.init.ref] 中指定了此类行为,该部分关于引用声明的初始化程序。生命周期扩展不能通过函数参数传递。 §12.2/5 [class.temporary]:



您可以查看 gotw-88 以获得有关此主题的扩展且更具可读性的讨论。

未定义的行为

那么你的代码正确吗?不,它的执行将导致未定义的行为。代码快照中的真正问题是未定义行为是由两个完全 合法 操作的混合引起的:构造函数的调用传递一个临时对象(其生命周期在构造函数块内)和引用的绑定(bind)构造函数定义。

编译器不够聪明,无法检测到这种爆炸性的语句组合,所以这就是您不会收到任何警告的原因。

关于c++ - 临时 : No compiler warning? 的绑定(bind)常量&,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27423364/

10-14 23:55