печать объекта, возвращенного по ссылке, неожиданно не приводит к мусору - PullRequest
0 голосов
/ 06 ноября 2018

В качестве упражнения я пишу класс, похожий на 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());
}

Я тестировал его с помощью MinGW в Windows 10.

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

1 Ответ

0 голосов
/ 06 ноября 2018

printf() не принимает никаких параметров по ссылке, только по значению. Таким образом, даже если data() возвращает ссылку int&, передача этой ссылки в printf() передаст значение ссылки int, а не саму ссылку. И %d ожидает значение int, так что все хорошо, мусор не выводится.

Это НЕ неопределенное поведение. Вот как передача ссылки на параметр передачи по значению должна работать, это очень определенное поведение. По сути, он делает это:

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