gpt4 book ai didi

c - 编译器是否足够智能来优化它?

转载 作者:行者123 更新时间:2023-11-30 21:29:08 25 4
gpt4 key购买 nike

在以下几行中:

typedef struct foo {.....} foo_t;
foo_t array[1000];
foo_t* ptr = &array[50];

最后一行相当于

 foo_t* ptr = array + 50

因为,假设 foo_t 很大,将 array[50] 转换为 foo_t 的实例,然后取地址。

最佳答案

假设有一个合理的编译器,编译器应该生成等价的:

ptr = (char*)array + 50 * sizeof(foo_t); 

对于这两种情况,是的。 (强制转换为 char* 只是为了解释需要将 sizeof(foo_t) 乘以到语句中。

确实没有其他方法可以找到 &array[50] 的值无论如何。

注意50 * sizeof(foo_t)的关键点是我们需要将索引相乘以生成字节地址值,然后再添加到 array的基地址。典型情况,地址为 array是恒定的并且偏移量是恒定的[sizeof(foo_t)本质上是常量,否则你无论如何都不能声明变量的数组],编译器当然会优化整个 array + 50 * sizeof(foo_t)这样它只是代码中的一个常量(一旦它被链接并重新定位为数据地址)。

如果50替换为 x ,一个仅在运行时已知的值,在加法之前会有一个乘法[如果被乘数足够简单,例如,乘法可以优化为更快的运算,例如x * 9 =x * 8 + x作为一条指令,因为支持乘以 1、2、4、8 和 16 - 至少在某些处理器,甚至 RISC 处理器中,乘法通常比一些加法和移位操作更复杂 - 小数字通常非常复杂这种方式很容易处理,但575或13412可能不太容易转换为少量简单运算,因此需要适当的乘法。

但无论哪种方式,&array[50] 的地址计算都是相同的。和array + 50 - 并且 99% 肯定会在编译时计算。如果在编译时未知,则对 array + x 执行相同的计算。 , x + array , &array[x]&x[array] - 因为array[x]*(array + x) (并且采用地址运算符只会删除对元素 1 的实际访问)在语言定义中是相同的,并且这种转换在编译阶段的早期发生,因此它们在后端之前变得无法区分实际上执行代码生成。

1在我的 Pascal 编译器中,我有一个用于抽象语法树类的函数,它执行 Address 操作。 ,对变量值的访问是 value = Load(AST.Address())Store(value, AST.Address())作为通用解决方案。请参阅:

General "Load value".

Calculate address of [multidimensional] array

关于c - 编译器是否足够智能来优化它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33963674/

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