首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否需要为所有成员对齐指向联合的指针

是否需要为所有成员对齐指向联合的指针
EN

Stack Overflow用户
提问于 2015-03-11 00:20:22
回答 2查看 83关注 0票数 2

给定的

代码语言:javascript
复制
typedef union { unsigned char b; long l; } BYTE_OR_LONG;

有一个函数合法吗?

代码语言:javascript
复制
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.
}

并将其称为

代码语言:javascript
复制
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,或者程序员只需要转换到联合类型的指针,以满足其中每个组成部分的每个对齐要求?

EN

回答 2

Stack Overflow用户

发布于 2015-03-11 02:04:18

这是否意味着保证指向联合类型的指针必须能够识别其中包含的任何类型的任何实例的实现?

很长的问题,简短的答案:是的。

(稍后我将深入研究标准参考)

基本上,这是因为结构/联合的第一个元素保证在它之前没有填充。

票数 0
EN

Stack Overflow用户

发布于 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的任何联合,而不一定是相反的方向。据我所知,一个工会的路线要求可能比所有会员都严格。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28968873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档