给定的
typedef union { unsigned char b; long l; } BYTE_OR_LONG;有一个函数合法吗?
unsigned long get_byte_or_long(BYTE_OR_LONG *it)
{
if (it->b)
return it->b;
else
return decode_long(it->l); // Platform-dependent method
// Could return (it), (it>>8), etc.
}并将其称为
void test()
{
long l = encode_long(12345678); // Platform-dependent; could return
// (it<<8), (it & 16777215), etc.
char b[2] = {12,34};
BYTE_OR_LONG *bl[3];
bl[0] = (BYTE_OR_LONG*)&l;
bl[1] = (BYTE_OR_LONG*)b;
bl[2] = (BYTE_OR_LONG*)(b+1);
for (int i=0; i<3; i++)
printf("%lu\n", get_byte_or_long(bl[i]));
}当然,构造未对齐的BYTE_OR_LONG *p,然后访问p->l将是未定义的行为。此外,即使是将未对齐的指针转换为指向(unsigned long*)的行为也是未定义的行为,因为实现可能不像char*那样需要这么多位。然而,有了工会,事情似乎就不明朗了。
据我所知,指向联合的指针应该等同于指向其任何元素的指针。这是否意味着需要保证指向联合类型的指针必须能够识别其中包含的任何类型的任何实例的实现,因此BYTE_OR_LONG*必须能够识别任何unsigned char,或者程序员只需要转换到联合类型的指针,以满足其中每个组成部分的每个对齐要求?
发布于 2015-03-11 02:04:18
这是否意味着保证指向联合类型的指针必须能够识别其中包含的任何类型的任何实例的实现?
很长的问题,简短的答案:是的。
(稍后我将深入研究标准参考)
基本上,这是因为结构/联合的第一个元素保证在它之前没有填充。
发布于 2015-03-11 19:22:21
指向对象类型的指针可以转换为指向不同对象类型的指针。如果生成的指针未正确对齐...对于被引用的类型,行为是未定义的。C11 (n1570) 6.3.2.3 p7
我找不到任何关于联合对齐要求的明确保证,因此到联合指针的转换看起来并不严格符合。在我的机器上,_Alignof(char)是1,但_Alignof(BYTE_OR_LONG)是4。
这是否意味着保证指向联合类型的指针必须能够识别其中包含的任何类型的任何实例所需的实现[因此
BYTE_OR_LONG*必须能够识别任何无符号字符],或者程序员是否只需要转换到联合类型的指针,以满足其中每个组成部分的每个对齐要求?
不,指向T的指针可以指向包含T的任何联合,而不一定是相反的方向。据我所知,一个工会的路线要求可能比所有会员都严格。
https://stackoverflow.com/questions/28968873
复制相似问题