如何消除GCC编译器的‘不兼容指针类型’警告?
解决char指针数组拷贝函数的const警告问题
首先说清楚为啥会出现这两个警告:
- 实参类型不兼容:C语言不允许把
char**隐式转成const char**,这是类型安全限制。举个例子,如果允许这种转换,你可以通过const char**把一个const char*赋值给char*,后续就能通过这个char*修改原本是const的字符串,直接违反const的语义。 - 赋值丢弃const限定符:函数里你把
src[i](const char*类型)赋值给dst[i](char*类型),编译器认为你把const限定的指针转成了非const,可能带来风险,所以触发警告。
你完全不用去掉const修饰,只要调整const的位置就能实现“不修改src指向内容”的语义标识:
正确的函数声明方案
如果只是要保证不修改src里的字符串内容,同时允许修改dst里的指针指向的内容,函数声明应该写成:
void word_arr_copy(const char * const *src, char **dst, int arr_size)
这里的const char * const *src两层const分别表示:
- 最内层
const char:不会通过src修改字符串里的字符; - 中间的
const:不会修改src数组里的指针指向(也就是不会改src[i]指向哪个字符串)。
这个声明下,char**类型的实参可以隐式传给const char* const*的形参,不会触发类型不兼容的警告。
处理赋值警告
函数内部拷贝指针时,因为src[i]是const char*,dst[i]是char*,直接赋值会触发丢弃const的警告。如果你确定dst后续操作不会修改原本是const的内容(比如src指向的本来就是可修改的char数组),可以用显式转换消除警告:
for (int i = 0; i < arr_size; i++) { dst[i] = (char*)src[i]; }
如果你的目标数组dst也不需要修改字符串内容,直接把dst的形参改成const char**就行,这样赋值完全不会有警告:
void word_arr_copy(const char * const *src, const char **dst, int arr_size)
内部直接写dst[i] = src[i];即可。
内容的提问来源于stack exchange,提问作者Fyodor
相关产品推荐
相关产品推荐

