Этот вопрос навеян кодом из этого вопроса, скопированным ниже, который выполняет недопустимый каламбур с помощью указателя:
# include <stdio.h>
int main()
{
char p[]={0x01,0x02,0x03,0x04};
int *q = p;
printf("%x",*q);
return 0;
}
У меня вопрос: легальна ли следующая версия приведенного выше кода? Я совершенно не уверен в преобразовании указателя на char в указатель на объединение, содержащее массив char. Многие вопросы о каламбуре типов здесь, в SO, но я не нашел дубликата, который охватывает использование указателя таким образом.
#include <stdio.h>
#include <stdint.h>
union char_int {
char p[4];
int32_t q;
};
int main()
{
char p[]={0x01,0x02,0x03,0x04};
int *q = &(((union char_int *)p)->q);
printf("%x",*q);
return 0;
}
В связи с этим, я считаю, что эти байты сформируют законное значение int32_t
для всех возможных представлений, разрешенных стандартом, но если кто-то может подтвердить эту дополнительную деталь, это тоже было бы здорово.
(union char_int *)p
в целом не определяется стандартом C из-за C 2018 6.3.2.3 7: «Указатель на тип объекта может быть преобразован в указатель на другой тип объекта. Если результирующий указатель неправильно выровнен для указанного типа, поведение не определено ... «еслиp
оказывается выровненным, как необходимо дляunion char_int
, тогда стандарт говорит:« при повторном преобразовании результат должен сравниваться с исходным указателем. . » В стандарте не говорится, что этот указатель действительно имеет какое-либо значение, которое иначе работает какunion char_int *
. - person Eric Postpischil   schedule 06.10.2019union char_int *x = (union char_int *) p;
, и это успешно, потому что выравнивание происходит, стандарт ничего не говорит о значенииx
, кроме(char *) x
, производит что-то, что сравнивается сp
. Значениеx
не обязательно является допустимым адресом, иначе*x
может относиться к совершенно другой памяти, чемp
, например. - person Eric Postpischil   schedule 06.10.2019*q
влияет базовое целочисленное представление реализации (в основном, порядок байтов, но потенциально платформа может не использовать дополнение до двух). И, как указывалось выше, оба значения не определены из-за алигментации. - person Graeme   schedule 06.10.2019union
, и мы все равно не приводим из его адреса, так что это ничего не говорит об этом случае. - person hyde   schedule 06.10.2019