Вызывает ли swap() неопределенное поведение?
Я пытаюсь понять условия на std::swap
из [C++11: utility.swap]. Шаблон определяется как
template <typename T> void swap(T &, T &)
(плюс некоторые noexcept
детали) и как результат "обмена значениями, хранящимися в двух местах".
У следующей программы есть четкие определения?
#include <utility>
int main()
{
int m, n;
std::swap(m, n);
}
Если бы я написал код подкачки сам (т.е. int tmp = m; m = n; n = tmp;
), он будет иметь неопределенное поведение, поскольку попытается преобразовать значение lvalue в rvalue для неинициализированного объекта. Но стандарт std::swap
Функция, похоже, не имеет каких-либо условий, наложенных на нее, и нельзя сделать вывод из спецификации, что существует какое-либо значение lvalue-to-rval и, следовательно, UB.
Требует ли стандарт std::swap
выполнить магию, которая четко определена на неинициализированных объектах?
Чтобы прояснить вопрос, рассмотрим функцию void f(int & n) { n = 25; }
, который никогда не имеет неопределенного поведения (так как он не читает из n
).
2 ответа
Очень хороший вопрос Тем не менее, я бы сказал, что это покрыто [res.on.arguments]§1:
Каждое из следующих условий относится ко всем аргументам функций, определенных в стандартной библиотеке C++, если явно не указано иное.
- Если аргумент функции имеет недопустимое значение (например, значение вне домена функции или указатель, недопустимый для ее предполагаемого использования), поведение не определено.
Для решения вашей проблемы о f(n)
, функция f
Исходя из вашего вопроса, он не является частью стандартной библиотеки C++, и, следовательно, вышеприведенное предложение к нему не относится.
Поскольку значение M не определено, я ожидаю, что оно испортит вызов подкачки. Носовые Демоны могут летать, когда вызывается своп.