通过引用返回的对象的printf-ing不会产生垃圾

时间:2018-11-05 21:16:54

标签: c++ variadic-functions

作为练习,我正在编写类似于std::lock_guard<>的类,其中包装了类T。我添加了一个data方法,该方法通过引用返回包装的东西。

我使用包装的整数对其进行了测试,并尝试将整数传递给printf("%d\n, ..."),在某种程度上绕过了类型系统。由于宽度问题,崩溃或其他原因,我希望看到垃圾,指针或指针的前半部分。

令我惊讶的是,代码按预期工作了……这表明我的按引用返回方式的模型是错误的……或者这里存在未定义的行为,并且代码恰好起作用了,但不能保证

将按引用返回的事物传递给诸如printf之类的C风格可变函数时,是否可以将按引用返回的事物视为实际事物的实例?

这是代码的简化版本,其中仅包含相关的方法和字段。

#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());
}

我在Windows 10上使用MinGW对其进行了测试。

$ g++ -Wall -Werror -pedantic -std=c++11 .\return_int_by_ref.cpp
$ .\a.exe
27

1 个答案:

答案 0 :(得分:4)

printf()不会通过引用仅接受值的任何参数。因此,即使data()返回一个int&引用,将该引用传递给printf()也会传递所引用的int value ,而不是引用自己。并且%d期望一个int值,所以一切都很好,没有垃圾输出。

这不是未定义的行为。这是假定传递给值传递参数的引用的方式,这是非常定义的行为。本质上是这样做的:

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