为何GCC会移除&&右操作数的数组边界检查,却保留左操作数的?
问题:GCC为何忽略
idx < ARRAY_LENGTH条件生成相同汇编? 代码片段
#define ARRAY_LENGTH 666 int g_sum = 0; extern int *g_ptrArray[ ARRAY_LENGTH ]; void test() { unsigned int idx = 0; // 可启用或禁用while循环中的"idx < ARRAY_LENGTH"检查 while( g_ptrArray[ idx ] != nullptr /* && idx < ARRAY_LENGTH */ ) { g_sum += *g_ptrArray[ idx ]; ++idx; } return; }
编译场景
使用GCC 12.2.0编译器并带-Os选项编译以下两种情况:
- while循环条件为
g_ptrArray[ idx ] != nullptr - while循环条件为
g_ptrArray[ idx ] != nullptr && idx < ARRAY_LENGTH
两种情况生成的汇编代码完全一致,且未对变量idx与ARRAY_LENGTH进行检查:
生成的汇编代码
test(): ldr r2, .L4 ldr r1, .L4+4 .L2: ldr r3, [r2], #4 cbnz r3, .L3 bx lr .L3: ldr r3, [r3] ldr r0, [r1] add r3, r3, r0 str r3, [r1] b .L2 .L4: .word g_ptrArray .word .LANCHOR0 g_sum: .space 4
核心疑问
为何编译器会为两种情况生成完全相同的汇编,甚至忽略代码中存在的idx < ARRAY_LENGTH条件?请解释编译器做出该判断的规则或流程。
补充说明
若将条件顺序改为idx < ARRAY_LENGTH && g_ptrArray[ idx ] != nullptr,生成的汇编会包含idx的检查。
内容的提问来源于stack exchange,提问作者cerveka2
相关产品推荐
相关产品推荐

