gpt4 book ai didi

c - 使用指向结构成员的指针时是否适用严格别名?

转载 作者:太空狗 更新时间:2023-10-29 15:19:15 26 4
gpt4 key购买 nike

test_func 当两个参数部分重叠时,以下代码片段是否会在严格的别名规则下触发未定义的行为?

即第二个参数是第一个参数的成员:

#include <stdio.h>

typedef struct
{
//... Other fields
int x;
//... Other fields
} A;

int test_func(A *a, int *x)
{
a->x = 0;
*x = 1;
return a->x;
}

int main()
{
A a = {0};

printf("%d\n", test_func(&a, &a.x));

return 0;
}

基于 A*int* 不会别名的假设,是否允许编译器认为 test_func 只会返回 0?所以 *x 不能覆盖成员?

最佳答案

Strict aliasing指的是将指针转换为另一种指针类型,然后访问其内容。严格别名意味着涉及的指向类型必须兼容。这不适用于此处。

但是有术语指针别名,意思是两个指针可以引用同一内存。不允许编译器假定这里是这种情况。如果它想要像您描述的那样进行优化,它可能必须添加机器代码来比较指针,以确定它们是否相同。这本身会使函数稍微变慢。

为了帮助编译器优化此类代码,您可以将指针声明为restrict,它告诉编译器程序员保证指针不会指向同一内存。

您使用 gcc -O3 编译的函数生成此机器代码:

0x00402D09  mov    $0x1,%edx

这基本上意味着整个函数被替换(内联)为“将 a.x 设置为 1”。

但是如果我将你的函数重写为

int test_func(A* restrict a, int* restrict x)
{
a->x = 0;
*x = 1;
return a->x;
}

并用gcc -O3编译,它返回0。因为我现在已经告诉编译器a->Xx不要指向同一内存,因此可以假设 *x = 1; 不会影响结果并跳过行 *x = 1; 或在它之前排序a->x = 0; 行。

限制版本的优化机器代码实际上跳过了整个函数调用,因为它知道根据您的初始化值已经为 0。

这当然是一个错误,但程序员应该为此负责,因为粗心地使用了 restrict

关于c - 使用指向结构成员的指针时是否适用严格别名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42025337/

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