Строгие правила псевдонимов не заботятся о промежуточных приведениях.Они заботятся только о типе указателя, который в конечном итоге используется для доступа к объекту, и об исходном типе самого объекта (технически это «эффективный тип», но это сейчас не важно).
В вашем примере кода, вы берете адрес int
.Результат имеет тип int *
.Вы приводите этот указатель к char *
, вы снова приводите его к int *
, и только тогда вы разыменовываете его.Тип указателя, используемого при доступе, - int *
, а тип объекта, на который указывает объект, - int
, поэтому у правил строгого алиасинга нет проблем.
Вы правы, что правила строгого алиасингаасимметричный относительно char
, но это имеет значение только тогда, когда либо тип самого объекта равен char
, либо тип указателя, используемого при доступе, равен char
:
char x[sizeof(int)] = { 0 };
*(int *)x = 1; // undefined behavior
int y = 1234;
*(char *)y = 0; // valid; value of y becomes unspecified
Теоретически,приведение между двумя типами указателей может потерять информацию, но не при приведении из другого типа к char *
и обратно.Кроме того, это относится только к компьютерам, с которыми вы вряд ли столкнетесь в наши дни.Я не могу вспомнить пример.