C语言地址减法触发C4047间接级别不同警告问题排查
C4047地址减法编译警告原因与修复
触发的警告信息如下:
C4047 '-' : 'char' differs in levels of indirection from 'char ()[12]'
警告根因
参与减法运算的两个操作数指针类型不匹配,不符合C语言指针运算规则:
pch的类型为char*,是指向单个char类型元素的指针&Origi的类型为char (*)[12],是指向长度为12的char数组的数组指针,二者间接访问层级不一致,无法直接做减法计算偏移。
注意:Origi和&Origi的数值地址完全相同,都指向数组起始内存位置,但二者类型完全不同,指针运算的步长规则存在本质区别:
char*类型指针偏移1个单位的步长为1字节,对应单个char元素的长度char (*)[12]类型指针偏移1个单位的步长为12字节,对应整个长度为12的char数组总长度
对不同类型的指针直接做减法属于未定义行为,运行时大概率得到不符合预期的结果。
修复方案
要计算pch相对于Origi数组起始位置的元素偏移,直接使用数组名Origi作为减数即可。C语言中数组名在表达式中会自动退化为指向数组首元素的char*类型指针,和pch的类型完全匹配,二者做减法得到的结果就是指针间隔的char元素个数,也就是需要的偏移量。
修正后的代码如下:
#include <stdio.h> #include <string.h> int main() { char Origi[] = "Hallo Welt."; char* pch = strstr(Origi, "Welt"); // 直接使用退化为char*的数组名参与运算,类型完全匹配 printf("%d\n", pch - Origi); printf("%c\n", Origi[pch - Origi]); return 0; }
上述代码运行后会输出偏移量6,以及对应位置的字符W,符合预期逻辑。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

