gpt4 book ai didi

c - 实践中的严格别名

转载 作者:太空宇宙 更新时间:2023-11-04 00:02:08 25 4
gpt4 key购买 nike

像下面这样的 C11 代码是未定义的行为:

// test.c
#include <stdio.h>

struct point2d {
int x, y;
};

struct point3d {
int x, y, z;
};

typedef struct point2d point2d;
typedef struct point3d point3d;

int foo(point2d *p, point3d *q) {
p->x = -1;
p->y = -2;
q->x = 1;
q->y = 2;
q->z = 3;
return p->x;
}

int main(void) {
point3d r;
int n = foo((point2d *) &r, &r);

printf("%d\n", n);
return 0;
}

事实上,它是:

wrc@raspberrypi:~ $ gcc -O0 test.c -o test; ./test
1
wrc@raspberrypi:~ $ gcc -O3 test.c -o test; ./test
-1

C11 标准说 (6.5/7):

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

  • a type compatible with the effective type of the object,

  • a qualified version of a type compatible with the effective type of the object,

  • a type that is the signed or unsigned type corresponding to the effective type of the object,

  • a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,

  • an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or

  • a character type.

我的问题是关于 this一种技术,您尝试通过将指向较大结构的指针转换为指向较小结构的指针来隐藏信息,该结构不包含较大结构的所有成员。

这里是相关结构定义的总结:

struct _GRealArray
{
guint8 *data;
guint len;
guint alloc;
guint elt_size;
guint zero_terminated : 1;
guint clear : 1;
gint ref_count;
GDestroyNotify clear_func;
};

struct _GArray
{
gchar *data;
guint len;
};

typedef struct _GRealArray GRealArray;
typedef struct _GArray GArray;

这样的技术是否已经违反了标准?如果不是:有什么区别?如果是:为什么这里不重要?在这种情况下,是否有一些实用指南可以让您事实上违反标准而不会造成不良后果(与上面的 test.c 示例相反)?

最佳答案

Garray 示例将遵循相同的规则,如果它会强调它们的话,但它似乎在小心地避免这种情况。

对于用户代码,两种类型之间永远不会出现别名冲突,因为如果我没看错的话,GRealArray 类型是不可见的,所以所有这些别名问题都不会发生在用户中这两种类型的代码。

对于实现的内部代码,似乎不会出现别名,原因很简单,即每个函数中始终只有一个数组可见。或者更直接地说,

the aliasing rules only apply if there is potential aliasing.

即使可以,如果该实现始终对它处理的两个不同指针使用相同的类型,编译器仍然必须假设两个这样的指针可以指向同一个对象。

顺便说一句,如果您指向的代码的行为定义明确,这只会回答您的直接问题。这将要求对该代码进行深入审查。

关于c - 实践中的严格别名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38800455/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com