2013-07-06 2 views
5

Вызывает ли следующий код какой-либо тип определенного или неопределенного поведения? Я не уверен, как взаимодействие со ссылкой работает и мой Google/SO поиски идут пустыми:Назначение ссылочного аргумента локальной переменной

struct S { 
    int i; 
}; 

void Fn(S& s_arg) { 
    S s_fn{s_arg.i+1}; 
    s_arg = s_fn; 
} 

int main(int argc, char** argv) { 
    S s_main{15}; 
    Fn(s_main); 
    return 0; 
} 

Я не уверен, какой из двух должно произойти, когда назначение происходит в Fn:

  1. копия оператор присваивания по умолчанию s вызывается s_main (являющийся мишенью s_arg ссылки), копирование данных из локального (в Fn) s_fn в main «s местный s_main (через s_arg ссылки, делая все, что собственно и мы LL определены.
  2. Ссылка сама назначена и теперь относится к Fn местным s_fn. Fn теперь возвращает ссылку на локальные данные, и программа теперь просто ждет вызова другой функции с main, переписывая Fn локальный s_fn и вызывая общий хаос.

ответ

3

Здесь нет UB, ссылки указывают на s_main, и вы присваиваете значение s_fn s_arg (которое указывает на s_main), и все хорошо. Помните, что ссылки (в отличие от указателей) после инициализации не могут указывать на другой регион в памяти, что означает, что второй случай, о котором вы говорили, не может произойти.

+0

А, это то, что я получаю от обработки ссылок как прославленных указателей, я полагаю. Я предполагаю, что причина, по которой они не могут указывать на другой регион в памяти, состоит в том, что, поскольку в этом случае любое присвоение ссылки всегда вызывает оператор присваивания объекта, на который ссылается? – user2555367

+0

@ user2555367: Лучше думать о ссылках как псевдоним (другое имя), а не о указателях. –

2

Ссылки на C++ не могут быть «переустановлены» или сделаны для обращения к другому объекту, чем первоначально. Это исключает возможность № 2. Код в порядке.

3

Ссылки (в отличие от указателей) не могут изменить свой «адрес». Поэтому вызывается оператор присваивания.

Смежные вопросы