Целью std::launder
является не "подавление предупреждений", а удаление предположений, которые могут быть у компилятора C++.
Предупреждения о псевдонимах пытаются сообщить вам, что вы, возможно, делаете что-то, поведение которых не определено стандартом C++.
Компилятор может и делает предположения, что ваш код делает только то, что определено стандартом. Например, можно предположить, что указатель на значение const
после создания не будет изменен.
Компиляторы могут использовать это предположение, чтобы пропустить повторную выборку значения из памяти (и сохранить его в регистре) или даже вычислить его значение во время компиляции и на его основе устранить мертвый код. Он может предположить это, потому что любая программа, для которой это значение равно false, ведет себя неопределенно, поэтому любое поведение программы допустимо в соответствии со стандартом C++.
std::launder
был создан, чтобы позволить вам взять указатель на действительное const
значение, которое было законно изменено (скажем, путем создания нового объекта в его хранилище), и использовать этот указатель после модификации определенным образом ( так что это относится к новому объекту) и другим конкретным и подобным ситуациям (не думайте, что это просто «устраняет проблемы с псевдонимами»). __builtin_launder
в одном смысле будет функцией "noop", но в другом смысле она изменит тип ассемблерного кода, который можно сгенерировать вокруг. При этом определенные предположения о том, какое значение может быть получено на его входе, не могут быть сделаны в отношении его вывода. И некоторый код, который был бы UB на входном указателе, не является UB на выходном указателе.
Это экспертный инструмент. Я лично не стал бы использовать его, не проведя много стандартных копаний и перепроверив, что я не использовал его неправильно. Он был добавлен, потому что были определенные операции, которые кто-то доказал, что невозможно разумно выполнить стандартно совместимым способом, и теперь это позволяет разработчику библиотеки делать это эффективно.
person
Yakk - Adam Nevraumont
schedule
12.11.2018
std::launder
, и я надеялся, что, посмотрев пример реализации, все будет ясно. Да, это действительно мало что скажет вам о том, как работаетlaunder
. По определению, поведениеlaunder
существует вне нормальной работы C++. То есть вы не можете написать реализациюlaunder
. Это как просить реализациюsizeof
илиoffsetof
. - person Nicol Bolas   schedule 12.11.2018std::initializer_list
. - person alfC   schedule 12.11.2018initializer_list
самостоятельно. Чего вы не можете реализовать, так это резервного массива, на который ссылаетсяinitializer_list
, который создается с помощью списка инициализации в фигурных скобках. - person Nicol Bolas   schedule 12.11.2018