Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.95/21: Рейтинг темы: голосов - 21, средняя оценка - 4.95
225 / 52 / 4
Регистрация: 22.07.2018
Сообщений: 249
1

Зачем нужен std::launder?

22.07.2018, 13:26. Просмотров 4148. Ответов 17
Метки нет (Все метки)

Зачем нужен std::launder?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.07.2018, 13:26
Ответы с готовыми решениями:

Зачем нужен std::map
Почитал информацию об этом классе, но так и не понял, зачем он нужен?

Зачем в определении std::forward () нужен объект remove_reference?
Зачем в определении std::forward() нужен объект remove_reference ? И почему не могут быть выведены...

Зачем часто писать std::, если можно один раз using namespace std?
зачем часто писать std:: если можно один раз using namespace std?

Std::setfill - зачем
std::setfill - расскажите что означает этот код и как его приминяти

17
Don't worry, be happy
16958 / 9839 / 1895
Регистрация: 27.09.2012
Сообщений: 24,394
Записей в блоге: 2
22.07.2018, 13:48 2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <new>
 
struct Some
{
    int const x;
};
 
int main()
{
    Some * p = new Some{10};
    std::cout << p->x << std::endl;
    new (p) Some{20};//Пересоздали объект
    std::cout << p->x << std::endl;//Обращение к членам *p - undefined behavior
    std::cout << std::launder(p)->x << std::endl;//Ок
    return 0;
}
0
Заблокирован
22.07.2018, 13:52 3
Цитата Сообщение от Croessmah Посмотреть сообщение
std::cout << p->x << std::endl;//Обращение к членам *p - undefined behavior
почему UB, ведь указатель рабочий.
0
Don't worry, be happy
16958 / 9839 / 1895
Регистрация: 27.09.2012
Сообщений: 24,394
Записей в блоге: 2
22.07.2018, 14:06 4
https://stackoverflow.com/ques... stdlaunder
0
748 / 351 / 72
Регистрация: 10.06.2014
Сообщений: 2,368
22.07.2018, 14:08 5
_stanislav,
Дело не в том что рабочий указатель или нет.
Компилятор видит что Some::x на который указывает p является константой.
Теперь если компилятор "встретит" вызов Some::x от имени указателя p, то он имеет полное право не обращаться по данному адресу а просто подставить число которое мы присвоили const int x при создании объекта потому это что константа которая по идее не может быть изменена. А то что далее следует placement new - компилятору скорее всего чихать.

Поэтому мы не можем полагаться на то что из p->x будет получено новое значение, присвоенное при помощи placement new.
А вот если использовать std::launder, тогда чтение p->x уже будет происходить из памяти, и можно будет прочитать новое значение.
3
Заблокирован
22.07.2018, 15:42 6
Цитата Сообщение от Undisputed Посмотреть сообщение
Дело не в том что рабочий указатель или нет.
Компилятор видит что Some::x на который указывает p является константой.
Теперь если компилятор "встретит" вызов Some::x от имени указателя p, то он имеет полное право не обращаться по данному адресу а просто подставить число которое мы присвоили const int x при создании объекта потому это что константа которая по идее не может быть изменена. А то что далее следует placement new - компилятору скорее всего чихать.
Поэтому мы не можем полагаться на то что из p->x будет получено новое значение, присвоенное при помощи placement new.
А вот если использовать std::launder, тогда чтение p->x уже будет происходить из памяти, и можно будет прочитать новое значение.
как то не правильно все это
0
748 / 351 / 72
Регистрация: 10.06.2014
Сообщений: 2,368
22.07.2018, 16:25 7
_stanislav,
Почему не правильно? Можно конкретнее и с причинами?
0
_stanislav
22.07.2018, 16:34
  #8

Не по теме:

Undisputed, забей, мысли в слух, лень демагогию разводить

0
lArtl
22.07.2018, 20:07
  #9

Не по теме:

Цитата Сообщение от Undisputed Посмотреть сообщение
Почему не правильно? Можно конкретнее и с причинами?
По оценке, думаю это относится к языку)

0
Don't worry, be happy
16958 / 9839 / 1895
Регистрация: 27.09.2012
Сообщений: 24,394
Записей в блоге: 2
23.07.2018, 09:34 10
Приведу тогда более наглядный пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <cstdlib>
 
void bar(uint32_t * x, size_t s)//устанавливает в 0xFF s значений
{
    while (s-- > 0) {
        x[s] = 0xFF;
    }
}
 
 
void foo(uint64_t x)
{
    uint32_t * p = reinterpret_cast<uint32_t *>(&x);//ой, будем нарушать strict aliasing
    std::cout << x << std::endl;//20
    bar(p, 2);//ставим 32-ух разрядные половинки в 0xFF, конечно же, нарушили всё и вся
    std::cout << x << std::endl;//20? wtf? Долбанный strict aliasing, мы его нарушили и он нам мстит
    std::cout << *std::launder(&x) << std::endl;//Во, так норм
}
 
 
int main()
{
    foo(20);
}
https://wandbox.org/permlink/VhF2QbwGDfaZs1K8
2
Заблокирован
23.07.2018, 12:08 11
Croessmah, чёта студия 17 в х86 режиме launder не видит, что за ..., в х64 видит.
0
Заблокирован
23.07.2018, 12:17 12
Цитата Сообщение от Croessmah Посмотреть сообщение
std::cout << *std::launder(&x) << std::endl;//Во, так норм
это норм?
0
Миниатюры
Зачем нужен std::launder?  
Форумчанин
Эксперт CЭксперт С++
8161 / 5009 / 1436
Регистрация: 29.11.2010
Сообщений: 13,455
23.07.2018, 12:29 13
Цитата Сообщение от argcargv Посмотреть сообщение
Зачем нужен std::launder?
Это очень специфическая вещь. Есть подозрение, что нужен он скорее разработчикам компиляторов.
Связан он с placement new и оптимизациями компилятора для констант.
Если в вашем коде возникла необходимость в std::launder, то скорее надо код переписать, чем внедрять эту функцию.
Вот здесь есть парочка примером как он работает и как не надо делать в prod коде.
https://en.cppreference.com/w/cpp/utility/launder
1
Заблокирован
23.07.2018, 12:46 14
как я понял, просто читает данные непосредственно из памяти вне всяких оптимизаций?
0
284 / 175 / 21
Регистрация: 16.02.2018
Сообщений: 666
23.07.2018, 16:04 15
Цитата Сообщение от Croessmah Посмотреть сообщение
Приведу тогда более наглядный пример:
И что он должен демонстрировать?
Нарушение string aliasing это UB и std::launder это не отменяет.

Добавлено через 2 минуты
Цитата Сообщение от _stanislav Посмотреть сообщение
это норм?
Даже вывод
Код
20
20
20
будет норм.
0
Заблокирован
23.07.2018, 16:42 16

Не по теме:

Цитата Сообщение от rat0r Посмотреть сообщение
будет норм.
я тебе не верю

0
Evg
Эксперт CАвтор FAQ
21148 / 8164 / 628
Регистрация: 30.03.2009
Сообщений: 22,464
Записей в блоге: 30
15.01.2019, 20:05 17
Цитата Сообщение от Croessmah Посмотреть сообщение
Приведу тогда более наглядный пример:
Только вот я не уверен, что тест корректный. В процедуре bar было нарушение strict-aliasing'а. Но хз, позволяет ли такое нарушение делать std::launder

Добавлено через 3 часа 18 минут
В примере из поста #10 имеем следующее. Вызов функции bar приводит к нарушению strict aliasing'а. В режиме с оптимизациями на некотором наборе компиляторов это приведёт к ошибке исполнения, т.к. отработает оптимизация с условным названием "strict aliasing", которая будет считать, что записи по указателю типа int32_t не могут модифицировать переменную типа int64_t. Использование std::launder, упрощённо говоря, отменяет данную оптимизацию конкретно в строке 18 и как последствие тест как бы заработает. Но при этом он по прежнему остаётся некорректным, хотя в какой-то мере демонстрирует принцип работы std::launder

Цитата Сообщение от argcargv Посмотреть сообщение
Зачем нужен std::launder?
Если я правильно понял всю эту наноконцепцию. Упрощённо говоря, std::launder рожает "новый указатель", значение которого равно "старому указателю" (т.е. аргументу std::launder). Но при этом внутри компилятора новый указатель теряет все вычисленные оптимизатором свойства старого указателя. Т.е. является как бы барьером для некоторых оптимизаций/анализов компилятора. Получается, что std::launder является борьбой языка Си++ с собственными же концепциями

Цитата Сообщение от MrGluck Посмотреть сообщение
Есть подозрение, что нужен он скорее разработчикам компиляторов
Да нет, разработчики компилятора точно не при чём. Я бы сказал так, что функциональность std::launder - это то, что понятно для разработчиков компилятора и не понятно для большого количества нормальных людей

Цитата Сообщение от MrGluck Посмотреть сообщение
Если в вашем коде возникла необходимость в std::launder, то скорее надо код переписать, чем внедрять эту функцию
Вот тут соглашусь
2
Don't worry, be happy
16958 / 9839 / 1895
Регистрация: 27.09.2012
Сообщений: 24,394
Записей в блоге: 2
15.01.2019, 22:13 18
Цитата Сообщение от Evg Посмотреть сообщение
Но при этом внутри компилятора новый указатель теряет все вычисленные оптимизатором свойства старого указателя. Т.е. является как бы барьером для некоторых оптимизаций/анализов компилятора.
Кстати, в стандарте оно так и описывается.
16.6.4 Pointer optimization barrier
C++
template<class T> [[nodiscard]] constexpr T* launder(T* p) noexcept;
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.01.2019, 22:13

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Зачем указывать using namespace std
Здравствуйте. Вроде разобрался с циклами, ветвлением, базовыми типами данных. Остается не...

Зачем в команды ввода/вывода добавляют std::
Я начал кодить совсем недавно. И я не могу понять, почему в команды ввода/вывода добавляют std::...

Зачем std::set имеет в наличии не константный итератор?
Сабж. Зачем? Вроде бы смысла нету. Элементы std::set нельзя модифицировать. Нельзя написать...

Std::ios::binary зачем нужно это для записи структур
зачем нужно это для записи структур ? гугл чёткого ответа не дал


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.