修复与通用指针(void指针)相关的C语言编译警告
解决通用指针类型不兼容的编译警告
你的程序能正常运行且Valgrind无内存错误,说明逻辑是对的,但这些编译警告是因为C语言里void**和具体类型的二级指针(比如Cities**、Data**)之间不能隐式转换,编译器无法确认你已经做了正确的类型映射,所以抛出警告。下面给你两种简单的修复方案:
方案一:直接在调用时显式转换(推荐)
完全不需要castHeadTail函数,直接在readFile里根据city参数,把void**类型的head和tail强制转换成对应函数需要的指针类型即可。修改后的代码如下:
// 删掉原来的castHeadTail(&head, &tail, city);调用 if (city) { // 显式将void**转为Cities** readCities((Cities**)head, (Cities**)tail, line); } else { // 显式将void**转为Data** readCountries((Data**)head, (Data**)tail, line, size); }
这样编译器明确知道你要做类型转换,就不会再报参数类型不兼容的警告了。
方案二:修正castHeadTail函数(如果想保留该函数)
如果一定要保留castHeadTail的设计,需要调整函数的逻辑,让它返回转换后的类型指针,而不是直接修改传入的void***参数。修改后的函数和调用方式如下:
// 重新实现castHeadTail void castHeadTail(void** head, void** tail, int city, void** out_typed_head, void** out_typed_tail) { if (city) { // 将void**转为Cities**后,再转为void*返回 *out_typed_head = (void*)((Cities**)head); *out_typed_tail = (void*)((Cities**)tail); } else { // 将void**转为Data**后,再转为void*返回 *out_typed_head = (void*)((Data**)head); *out_typed_tail = (void*)((Data**)tail); } } // 在readFile里调用 void* typed_head, *typed_tail; castHeadTail(head, tail, city, &typed_head, &typed_tail); if (city) { readCities((Cities**)typed_head, (Cities**)typed_tail, line); } else { readCountries((Data**)typed_head, (Data**)typed_tail, line, size); }
为什么原来的castHeadTail会报错?
原来的函数里,你试图把void**类型的*head转换成Cities**后再赋值给*head(还是void**类型),这属于不同指针类型的赋值,C语言不允许隐式转换,所以编译器会抛出警告。本质上,void**和Cities**是两种不同的指针类型,不能直接互相赋值,必须通过显式强制转换告知编译器你的意图。
内容的提问来源于stack exchange,提问作者chilliefiber
相关产品推荐
相关产品推荐

