GCC 4.9下指针赋值给const指针的警告原因咨询
指针赋值类型不兼容警告问题
相关代码
char a = 0; char b[20] = {0}; char c[][20] = {{0}}; const char *aPtr; const char *bPtr; const char (*cPtr)[20]; char (*dPtr)[20]; void test(void) { aPtr = &a; bPtr = b; dPtr = &b; dPtr = c; cPtr = c; // warning here }
触发的警告信息
../source/bsw/user/PackParam_user.c:21:10: warning: assignment from incompatible pointer type
cPtr = c;
^
使用GCC 4.9编译器,仅cPtr = c;这一行触发类型不兼容警告,其他赋值语句均无警告,以下是原因分析:
原因拆解
1. 先明确各变量的本质类型
c是二维char数组,定义为char c[][20],在表达式中使用时会隐式转换为指向其首元素的指针,也就是char (*)[20](指向包含20个普通char的数组的指针)。cPtr的类型是const char (*)[20](指向包含20个const char的数组的指针)。dPtr的类型是char (*)[20],和c转换后的指针类型完全匹配,所以dPtr = c;无警告。
2. 为什么cPtr = c;不兼容?
C语言的const限定规则里,指向单个元素的指针可以隐式从非const转const(比如char*转const char*,这就是aPtr = &a;、bPtr = b;合法的原因),但指向数组的指针不支持这种跨层级的隐式转换:char (*)[20]和const char (*)[20]是完全不同的指针类型——前者指向的数组元素是普通char,后者指向的数组元素是const char,这种转换不符合标准C的隐式转换规则,因此GCC会抛出警告。
3. 其他赋值无警告的原因
aPtr = &a;:&a是char*,隐式转const char*符合标准规则。bPtr = b;:一维数组b转换为char*,再转const char*合法。dPtr = &b;:&b的类型是char (*)[20],和dPtr类型完全匹配。
如果要消除cPtr = c;的警告,需要显式强制类型转换:
cPtr = (const char (*)[20])c;
内容的提问来源于stack exchange,提问作者yyd
相关产品推荐
相关产品推荐

