【发布时间】:2018-09-03 10:58:57
【问题描述】:
我听说过关于 C 标准在多大程度上保证结构布局一致性的相互矛盾的事情。有限范围的争论提到了严格的别名规则。例如,比较这两个答案:https://stackoverflow.com/a/3766251/1306666 和 https://stackoverflow.com/a/3766967/1306666。
在下面的代码中,我假设在所有结构 foo、bar 和 struct { char *id; } 中 char *id 位于同一个位置,如果它是唯一访问的成员,则可以安全地在它们之间进行转换。
不管转换是否会导致错误,它是否违反了严格的别名规则?
#include <string.h>
struct foo {
char *id;
int a;
};
struct bar {
char *id;
int x, y, z;
};
struct list {
struct list *next;
union {
struct foo *foop;
struct bar *barp;
void *either;
} ptr;
};
struct list *find_id(struct list *l, char *key)
{
while (l != NULL) {
/* cast to anonymous struct and dereferenced */
if (!strcmp(((struct { char *id; } *)(l->ptr.either))->id, key))
return l;
l = l->next;
}
return NULL;
}
gcc -o /dev/null -Wstrict-aliasing test.c
注意gcc 没有给出错误。
【问题讨论】:
-
“转换为匿名结构指针”中的“转换”在哪里——我确实看到了 initialization 和 conversion (
void *到struct list *)。 -
@chux
((struct { char *id; } *)(l->ptr.either))->idinfind_id() -
@chux 很难看,仔细看。
-
@chux 它采用
(type) object的形式,根据C89 标准的§3.3.4 是一个演员;见port70.net/~nsz/c/c89/c89-draft.html#3.3.4 -
@user3386109 啊,是的,我认为代码正在尝试具有相似语法的 复合文字 - 在这里不会有问题。
标签: c casting unions anonymous-struct