Я не знаю, почему следующий код работает нормально, без ошибок gcc
(-fstrict-aliasing -Wstrict-aliasing=1
).
#include <stdio.h>
int
main(void)
{
char n = 42;
char *p = &n;
int *q = (int *)p;
*q = 10;
printf("%d|%d\n", *p, *q);
return 0;
}
Если я буду следовать строгому правилу псевдонима:
n1570, § 6.5 Выражения
Доступ к сохраненному значению объекта должен осуществляться только выражением lvalue, которое имеет один из следующих типов:
- тип, совместимый с эффективным типом объекта,
- квалифицированная версия типа, совместимого с действующим типом объекта,
- тип, который представляет собой знаковый или беззнаковый тип, соответствующий действующему типу объекта,
- тип, который является типом со знаком или без знака, соответствующим квалифицированной версии действующего типа объекта,
- тип агрегата или объединения, который включает в себя один из вышеупомянутых типов среди своих членов (включая, рекурсивно, член субагрегата или содержащегося объединения), или
- символьный тип.
Но *q
не имеет типа, совместимого с *p
, ни квалифицированной версии, ни соответствующего знакового, ни беззнакового типа, ни символьного типа.
Итак, почему это разрешено?
*q
указывает на выделенное пространство для одного символа, вы записываете тамsizeof(int)
данные. - person Mat   schedule 09.09.2012char
,unsigned char
илиsigned char
: этот код не нарушает строгих правил псевдонима из-за последнего предложения. Тем не менее, у него есть другие проблемы, которые приводят к неопределенному поведению. - person cmaster - reinstate monica   schedule 23.12.2014int
. Я не вижу ничего, что позволяло бы получить доступ к объектам символьного типа черезint
lvalue. - person md5   schedule 24.12.2014