История изменений
Исправление gentoo_root, (текущая версия) :
Значит, если функция принимает char*, то за этим чаром может быть любой объект, т. к. к любому объекту можно обращаться как к char
Да.
Character pointer types are often used in the bytewise manipulation of objects; a byte stored through such a character pointer may well end up in an object of any type.
Через char * можно рулить байтиками объектов, байтики по этому указателю могут принадлежать любому объекту. Это означает всего лишь, что char * может оказаться указывающим на любой объект, это не значит, что если на что-то указывает char *, мы можем это переинтерпретировать как другой тип. Если бы было так, можно было бы объявить int a, привести (short *)(char *)&a и получить указатель уже на short. У меня есть такой пример, в нём ломается strict aliasing на gcc 4.9.2, x86_64:
#include <stdio.h>
// gcc 5.c -o 5 -O3 -Wall -Wextra -Wstrict-aliasing=3
// no warning
// gcc 5.c -o 5 -O3 -Wall -Wextra -Wstrict-aliasing=2
// no warning
// gcc 5.c -o 5 -O3 -Wall -Wextra -Wstrict-aliasing=1
// no warning
// strict aliasing is broken
int global;
int modify(char *test)
{
global = 'a';
*(short *)test = 'b';
return global;
}
int main()
{
printf("%c\n", modify((char *)&global));
return 0;
}
Программа выводит a, а с -fno-strict-aliasing выводит b.
Вот так вот. А объяснение простое — мы обращаемся к объекту эффективного типа int по lvalue типа short, а short не является совместимым типом с int и не подходит под остальные пункты.
Исходная версия gentoo_root, :
Значит, если функция принимает char*, то за этим чаром может быть любой объект, т. к. к любому объекту можно обращаться как к char
Да.
Character pointer types are often used in the bytewise manipulation of objects; a byte stored through such a character pointer may well end up in an object of any type.
Через char * можно рулить байтиками объектов, байтики по этому указателю могут принадлежать любому объекту. Это означает всего лишь, что char * может оказаться указывающим на любой объект, это не значит, что если на что-то указывает char *, мы можем это переинтерпретировать как другой тип. Если бы было так, можно было бы объявить int a, привести (short *)(char *)&a и получить указатель уже на short. У меня есть такой пример, в нём ломается strict aliasing на gcc 4.9.2, x86_64:
#include <stdio.h>
// gcc 5.c -o 5 -O3 -Wall -Wextra -Wstrict-aliasing=3
// no warning
// gcc 5.c -o 5 -O3 -Wall -Wextra -Wstrict-aliasing=2
// no warning
// gcc 5.c -o 5 -O3 -Wall -Wextra -Wstrict-aliasing=1
// no warning
// strict aliasing is broken
int global;
int modify(char *test)
{
global = 'a';
*(short *)test = 'b';
return global;
}
int main()
{
printf("%c\n", modify((char *)&global));
return 0;
}
Вот так вот. А объяснение простое — мы обращаемся к объекту эффективного типа int по lvalue типа short, а short не является совместимым типом с int и не подходит под остальные пункты.