Где я могу узнать, что на самом деле делает std::launder?

Я пытаюсь понять, что делает std::launder, и я надеялся, что, найдя пример реализации было бы понятно.

Где я могу найти пример реализации std::launder?

Когда я посмотрел в lbic++, я увидел такой код

  template<typename _Tp>
    [[nodiscard]] constexpr _Tp*
    launder(_Tp* __p) noexcept
    { return __builtin_launder(__p); }

Что заставляет меня думать, что это еще одна из тех магических функций компилятора.

Что потенциально может делать эта функция __builtin_launder? Она просто добавляет тег для подавления предупреждений компилятора об использовании псевдонимов?

Возможно ли понять std::launder с точки зрения __builtin_launder или это просто еще одна магия компилятора (хуки)?


person alfC    schedule 12.11.2018    source источник
comment
возможно, это поможет gcc.gnu.org/ml/libstdc++/2016- 10/msg00194.html   -  person OznOg    schedule 12.11.2018
comment
Вы только что привели пример реализации - я не понимаю вопроса. Вы спрашиваете, для чего нужна стирка?   -  person Barry    schedule 12.11.2018
comment
Я пытаюсь понять, что делает std::launder, и я надеялся, что, посмотрев пример реализации, все будет ясно. Да, это действительно мало что скажет вам о том, как работает launder. По определению, поведение launder существует вне нормальной работы C++. То есть вы не можете написать реализацию launder. Это как просить реализацию sizeof или offsetof.   -  person Nicol Bolas    schedule 12.11.2018
comment
@NicolBolas, .... или std::initializer_list.   -  person alfC    schedule 12.11.2018
comment
Можете посмотреть en.cppreference.com/w/cpp/utility/launder.   -  person 2785528    schedule 12.11.2018
comment
@alfC: На самом деле вы можете реализовать initializer_list самостоятельно. Чего вы не можете реализовать, так это резервного массива, на который ссылается initializer_list, который создается с помощью списка инициализации в фигурных скобках.   -  person Nicol Bolas    schedule 12.11.2018
comment
@NicolBolas Согласно указателям std, это тривиальные типы, поэтому функция идентификации является реализацией отмывания. Таким образом, 1_.   -  person curiousguy    schedule 01.12.2018


Ответы (1)


Целью std::launder является не "подавление предупреждений", а удаление предположений, которые могут быть у компилятора C++.

Предупреждения о псевдонимах пытаются сообщить вам, что вы, возможно, делаете что-то, поведение которых не определено стандартом C++.

Компилятор может и делает предположения, что ваш код делает только то, что определено стандартом. Например, можно предположить, что указатель на значение const после создания не будет изменен.

Компиляторы могут использовать это предположение, чтобы пропустить повторную выборку значения из памяти (и сохранить его в регистре) или даже вычислить его значение во время компиляции и на его основе устранить мертвый код. Он может предположить это, потому что любая программа, для которой это значение равно false, ведет себя неопределенно, поэтому любое поведение программы допустимо в соответствии со стандартом C++.

std::launder был создан, чтобы позволить вам взять указатель на действительное const значение, которое было законно изменено (скажем, путем создания нового объекта в его хранилище), и использовать этот указатель после модификации определенным образом ( так что это относится к новому объекту) и другим конкретным и подобным ситуациям (не думайте, что это просто «устраняет проблемы с псевдонимами»). __builtin_launder в одном смысле будет функцией "noop", но в другом смысле она изменит тип ассемблерного кода, который можно сгенерировать вокруг. При этом определенные предположения о том, какое значение может быть получено на его входе, не могут быть сделаны в отношении его вывода. И некоторый код, который был бы UB на входном указателе, не является UB на выходном указателе.

Это экспертный инструмент. Я лично не стал бы использовать его, не проведя много стандартных копаний и перепроверив, что я не использовал его неправильно. Он был добавлен, потому что были определенные операции, которые кто-то доказал, что невозможно разумно выполнить стандартно совместимым способом, и теперь это позволяет разработчику библиотеки делать это эффективно.

person Yakk - Adam Nevraumont    schedule 12.11.2018