gcc.gnu.org/bugzilla/show_bug.cgi?id=65752

у это неопределенное поведение?

struct s
{
    const int id; // <-- const member

    s(int id):
        id(id)
    {}

    s& operator =(const s& m) {
        return *new(this) s(m); // <-- undefined behavior?
    }
};

(Цитата из стандарта была бы хороша).

Этот вопрос возник изэтот ответ.

 DaBler24 нояб. 2017 г., 15:08
@BoPersson: Другое мнение, что я создаю новый объект в том же месте.
 Rakete111124 нояб. 2017 г., 15:54
@YSC Если деструктор тривиален (как в этом случае), то законно не называть его.timsong-cpp.github.io/cppwp/basic.life#5.sentence-1
 Passer By24 нояб. 2017 г., 15:43
Я отчетливо помню, как это было законно. @BoPerssonconst относится только к сроку службы объекта.
 Bo Persson24 нояб. 2017 г., 13:57
const int id; говорит, что ценностьid никогда не изменится. А потом ты это изменишь?
 Passer By24 нояб. 2017 г., 15:50
@YSC Деструкторы, не вызываемые, не являются неопределенным поведением. Вызов деструктора для недопустимого объекта.

Ответы на вопрос(1)

Решение Вопроса

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

Из[Basic.life] / 8 (акцент мой)

Если по истечении времени жизни объекта и до повторного использования или освобождения хранилища, которое занимал объект, в месте хранения, которое занимал исходный объект, создается новый объект, указатель, указывающий на исходный объект, ссылка, которая ссылка на исходный объект, или имя исходного объекта будет автоматически ссылаться на новый объект и, как только начнется время жизни нового объекта, может использоваться для управления новым объектом, если:

хранилище для нового объекта точно перекрывает место хранения, которое занимал исходный объект, и

новый объект того же типа, что и исходный объект (без учета cv-квалификаторов верхнего уровня), и

тип исходного объекта не является константным, и, если тип класса,не содержит нестатического члена данных, тип которого является константным или ссылочный тип, и

исходный объект был наиболее производным объектом типаT и новый объект является наиболее производным объектом типаT (то есть они не являются подобъектами базового класса).

Так как естьconst член вsиспользуя исходную переменную после вызоваoperator= будет UB.

s var{42};
var = s{420};         // OK
do_something(var.id); // UB! Reuses s through original name
do_something(std::launder(&var)->id);  // OK, this is what launder is used for
 DaBler24 нояб. 2017 г., 17:04
Хорошо, я понимаю. Благодарю.
 curiousguy07 июл. 2018 г., 00:17
 Passer By24 нояб. 2017 г., 16:47
@DaBler Технически, есть. Но я настоятельно рекомендую против этого.auto& ref = (var = s{420});, А потом использоватьref
 curiousguy06 июл. 2018 г., 23:37
@DaBler Технически, при строгом чтении в std, в распространенных реализациях, использование объекта указателя всегда гарантированно работало после этого трюка с изменением констант. Тем не менее, пока указатель содержит только адрес (номер). Тем не менее, это педантично и, конечно, НЕ предназначено, и люди, чья работа состоит в том, чтобы интерпретировать стандарт, не поддержат его. Ни один компилятор не изо всех сил поддержит это педантичное чтение.
 DaBler24 нояб. 2017 г., 16:44
Итак, правильно ли я понимаю, что не существует легального способа доступа к членам до C ++ 17?

Ваш ответ на вопрос