代码之家  ›  专栏  ›  技术社区  ›  Greg Nisbet

打印引用意外返回的对象不会产生垃圾

  •  -1
  • Greg Nisbet  · 技术社区  · 7 年前

    作为练习,我写了一个类似于 std::lock_guard<> 这是一个类的结束 T data 方法,该方法通过引用返回包装的对象。

    我用一个包装好的整数测试它,并尝试将整数传递给 printf("%d\n, ...") ,在一定程度上绕过了类型系统。我希望看到垃圾,或者指针,或者指针的前半部分,因为宽度问题,或者崩溃,或者别的什么。

    令我惊讶的是,代码按预期工作。。。这说明我的参照返回模式是错误的。。。或者这里有未定义的行为,代码刚好可以工作,但不能保证。

    当把一个引用返回的东西传递给一个C型的变量函数时,是否可以把它当作一个实际东西的实例 printf

    下面是代码的精简版本,只包含相关的方法和字段。

    #include <cstdio>
    
    struct int_holder {
    public:
        int m_data{27};
    public:
        int& data() {
            return this->m_data;
        }
    };
    
    int main() {
        int_holder h{};
        printf("%d\n", h.data());
    }
    

    我在windows10上用MinGW测试了它。

    $ g++ -Wall -Werror -pedantic -std=c++11 .\return_int_by_ref.cpp
    $ .\a.exe
    27
    
    1 回复  |  直到 7 年前
        1
  •  4
  •   Remy Lebeau    7 年前

    printf() data() 返回一个 int& 引用,将引用传递给 将通过 价值 int 被引用,而不是引用本身。以及 %d 期望 值,所以一切都很好,没有垃圾输出。

    这不是未定义的行为。这就是如何将引用传递给pass by value参数 为了工作,这是非常明确的行为。它基本上是这样做的:

    int &ref = h.data();
    int value = ref;
    printf("%d\n", value);