typedef struct  {  char   ch;  int   num;  }  st_t;
typedef union   {  char *pch;  st_t *pst;  }  un_t;

st_t st;
st.ch = 's';

un_t un = { &st.ch };
*un.pch = 'u';

printf("%c\n", un.pst->ch);  // expect: print the letter 'u'

据我所知,结构的第一个成员的地址和结构本身的地址是相同的,因此un可以通过访问stst.ch同时指向pstpch然而,C99标准似乎从来没有明确指出the sizes of different types of pointers are identical那么,我担心的是,代码是否会被破坏,比如违反严格的别名规则、未定义的行为等等。?

最佳答案

台词:

un_t un = {&st.ch};
*un.pch = 'u';

将结构的成员ch的地址分配给联合的成员pch,然后使用该指针将字符写入该地址这完全正确。
下面的行有问题:
printf("%c\n", un.pst->ch);

将读取联合体的成员(上次存储到的成员除外)。
以下可能是trap1表示2:
un.pst

1(引用自:ISO/IEC 9899-201x 6.2.6.1总则5)
某些对象表示不需要表示对象类型的值如果存储
对象的值具有这样的表示,并由左值表达式读取
没有字符类型,行为未定义如果提出这样的陈述
通过左值表达式修改对象的全部或任何部分的副作用
没有字符类型,行为未定义50)这种陈述被称为
陷阱的表现。
2(引用自:ISO/IEC 9899:201x 6.5.2.3结构和工会成员3脚注95)
如果用于读取联合对象内容的成员与上次使用的成员不同
在对象中存储一个值,将重新解释该值的对象表示的适当部分
作为6.2.6中描述的新类型的对象表示(有时称为“类型”的过程
双关语')这可能是一个陷阱表示。

10-07 16:45
查看更多