Чем больше я читаю, тем больше я смущаюсь.
Последний вопрос из близких ближе всего к моему вопросу, но я запутался со всеми словами об объекте жизни и особенно - нормально ли читать или нет.
Чтобы добраться до точки. Исправьте меня, если я ошибаюсь.
Это нормально, gcc не дает предупреждения, и я пытаюсь "читать тип T
(uint32_t
) через char*
":
uint32_t num = 0x01020304;
char* buff = reinterpret_cast< char* >( &num );
Но это "плохо" (также дает предупреждение), и я пытаюсь "по-другому":
char buff[ 4 ] = { 0x1, 0x2, 0x3, 0x4 };
uint32_t num = *reinterpret_cast< uint32_t* >( buff );
Как второй отличается от первого, особенно когда мы говорим о инструкциях по переупорядочению (для оптимизации)? Кроме того, добавление const
никак не изменит ситуацию.
Или это просто правильное правило, в котором четко говорится: "Это можно сделать в одном направлении, но не в другом"? Я не мог найти ничего в стандартах (искал это особенно в стандарте С++ 11).
Это то же самое для C и С++ (как я прочитал комментарий, подразумевая, что он отличается для двух языков)?
Я использовал union
для "обхода" этого, который по-прежнему кажется НЕ 100% OK, поскольку он не гарантируется стандартом (в котором говорится, что я могу полагаться только на значение, последний раз модифицированный в union
).
Итак, прочитав много, я теперь более смущен. Я думаю, что только memcpy
является "хорошим" решением?
Похожие вопросы:
- Что такое строгое правило псевдонимов?
- "разыменованный тип-указатель будет нарушать правила строгого сглаживания" предупреждение
- Правильно ли я понимаю строгое сглаживание C/С++?
- Строгое правило сглаживания и указатели char *
ИЗМЕНИТЬ
Ситуация в реальном мире: у меня есть сторонняя библиотека (http://www.fastcrypto.org/), которая вычисляет UMAC, а возвращаемое значение находится в char[ 4 ]
. Затем мне нужно преобразовать это в uint32_t
. И, кстати, lib часто использует такие вещи, как ((UINT32 *)pc->nonce)[0] = ((UINT32 *)nonce)[0]
. Так или иначе.
Кроме того, я спрашиваю, что правильно, а что не так и почему. Не только о переупорядочении, оптимизации и т.д. (Интересно то, что с -O0
нет предупреждений, только с -O2
).
И обратите внимание. Я знаю о большой/маленькой ситуации. Это не так. Я действительно хочу проигнорировать это утверждение. "Строгие правила псевдонимов" звучат как что-то действительно серьезное, гораздо более серьезное, чем неправильное утверждение. Я имею в виду - например, доступ к/изменению памяти, которая не должна быть затронута; любой вид UB вообще.
Цитаты из стандартов (C и С++) будут действительно оценены. Я ничего не мог найти о правилах псевдонимов или что-то в этом роде.