#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
было бы псевдонимом, но разрешено использовать символ для псевдонимов других объектов).