Нарушение правил строгого сглаживания

#c #strict-aliasing

#c #строгое сглаживание

Вопрос:

В этой ссылке из isocpp.org часто задаваемые вопросы в приведенном примере создается объект Fred с размещением new в буфере, который выделяется для другого объекта, т.Е. для

 char memory[sizeof(Fred)]
 

Насколько я знаю, строгие правила сглаживания позволяют нам делать обратное, т.Е. Для объекта любого типа нам разрешено char* указывать на него, и мы можем разыменовать этот указатель и использовать его по своему усмотрению.

Но здесь, в примере, происходит обратное. Чего мне не хватает?

Комментарии:

1. Что не так с вопросом, который дал мне отрицательный ответ?

2. есть слишком тупицы, которые не заботятся о них. Я дал 1. Не сдавайтесь, чтобы не отставать от вопроса, когда вы застряли. Веб-сайт предназначен для обучения.

3. Было бы лучше, если бы вопрос отображал в вопросе код, о котором вы спрашиваете, вместо того, чтобы иметь внешнюю ссылку, которая может меняться со временем, и имеет несколько примеров кода.

Ответ №1:

В правилах строгого сглаживания не упоминается, что Fred* должно быть приведено к char* . Только переменные типа char* и Fred* могут указывать на один и тот же объект и использоваться для доступа к нему.

Цитирование [basic.lval] параграф 8

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

  • динамический тип объекта,

    [..]

  • тип символа или символа без знака.

Комментарии:

1. Да, но я понимаю, что в примере происходит обратное. Значение объекта получает доступ из типа Fred . В этом фрагменте, который вы опубликовали, говорится о другом направлении, т.Е. О том, что объект Fred является доступом из типа char.

2. Также упоминается ли здесь «динамический тип» в терминах наследования?

3. @user183833 Фрагмент не навязывает ни того, ни другого направления. Они оба действительны в этом контексте. И да, это динамично с точки зрения наследования.

Ответ №2:

Placement-new создает новый объект. Он не присваивает псевдоним старому объекту. Считается, что старый объект ( char массив в этом примере) перестает существовать при выполнении placement-new .

Перед размещением-новое, есть хранилище, заполненное char объектами. После размещения-new хранилище заполняется одним Fred объектом.

Поскольку сглаживания нет, проблем со строгим сглаживанием нет.

Комментарии:

1. Я считаю, что использование memory after placement new в этом примере является неопределенным поведением. Это правильно? О чем place ?

2. Я думаю, что использование памяти после этого не будет неопределенным. Из-за рассказчика фрагмента, опубликованного выше. Итак, @M. M Я думаю, что я понял. Во-первых, если бы у кого-то сейчас был указатель char * на память, за пределами этой функции, и он знал, что там хранится объект типа Fred . Он хотел бы переинтерпретировать его Fred *. Причина, по которой ему разрешено это делать, заключается в том, что в этой ссылке 5 . Но тогда для разыменования ему понадобится один из маркеров из псевдонима типа снизу в этой ссылке, чтобы сохранить значение true, чтобы оправдать его. Верно? Если да, то какое?

3. Или даже в этом контексте это не считается сглаживанием?

4. @esam в этом коде нет неопределенного поведения.

5. @user183833 «сглаживание» использует значение lvalue одного типа для доступа к объекту другого типа. Чего не происходит в этом примере. В вашем случае (если я вас правильно понимаю) другой человек может использовать Fred или char для доступа к Fred объекту. (Использование char было бы псевдонимом, но разрешено использовать символ для псевдонимов других объектов).