2017-02-07 1 views
1

GCC (6.3.1 20170109) при компиляции следующей программыПочему я получаю предупреждение типа «пушечное» даже при использовании символа `char *`?

#include <stdio.h> 

int main(int argc, const char *argv[]) { 
    unsigned char x[] = {0x66, 0x19}; 
    printf("%i\n", ((short *)((char *)&x[0]))[0]); 
    return 0; 
} 

генерирует как предупреждение:

pun.c: В функции 'главной': pun.c: 5: 5: предупреждение: разыменования типа каламбурил указатель будет нарушать правила строгого сглаживания [-Wstrict-алиасы]

не должен набрать сглаживание разрешено при использовании char указателей?

ответ

3

Вот что C11 (или по крайней мере свободный проект N1570) должен сказать о ступенчатости:

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

  • типа совместим с эффективным типом объекта,
  • квалифицированной версии типа, совместимого с эффективным типом объекта,
  • типа, который является знаком или без знака типа, соответствующего эффективного типа объекта,
  • типа, который является знаком или без знака типа, соответствующий квалифицированной версия эффективного типа объекта,
  • в совокупный или союзный тип, который включает один из вышеупомянутых типов среди его членов (включая рекурсивно, член субагрегата или объединенного объединения) или
  • тип символа.
  • исключение типа

Символ означает, что вы можете получить доступ к любому типу через char* или unsigned char*, но это не означает, что вы можете получить доступ к char* с помощью любого типа. short* не соответствует другим критериям, перечисленным здесь для char*, поэтому это использование является неопределенным поведением.

Кроме того, вы могли бы нарушить требования к выравниванию, если это было разрешено безоговорочно:

short x[] = {1, 2}; 
char* alias = x; 
printf("%i\n", *(short*)&alias[1]); 
Смежные вопросы