gcc对void型指针的类型检查有问题?
创始人
2024-04-06 15:26:37

背景

前一段时间遇到一个问题,我调用了一个隔壁部门的库,这个库在调用前要创建context,程序退出前要销毁context,问题是销毁的时候,出现段错误了。
经过一番定位,发现是库的销毁接口跟库的常规处理接口稍有差别

typedef void *xxx_handle;
//常规接口
int xxx_proc(xxx_handle h, int arg);
//创建接口
xxx_handle xxx_create();
//销毁接口
int xxx_destroy(xxx_handle *ph);

销毁接口的第一个入参类型不是void*,而是void **
等等,为什么编译没有告警指针类型不匹配?

gcc对void *的检查

下面这行代码不会有任何告警,但指针类型其实是不匹配的:

#includetypedef void *handle;void f(handle *ph) {
}int main() {handle h = NULL;f(h);return 0;
}

这说明,gcc不会告警一级void指针和二级void指针的类型不匹配!

尝试用g++编译问题代码,直接报error:

test_void_ptr.c: In function ‘int main()’:
test_void_ptr.c:10:8: error: invalid conversion from ‘handle {aka void*}’ to ‘void**’ [-fpermissive]f(h);^
test_void_ptr.c:5:6: note:   initializing argument 1 of ‘void f(void**)’void f(handle *ph) {^

看样子是C语言编译器特有的现象,C还是太permissive了。

尝试规避

但是你如果把void关键字替换成int,其他不做修改,则gcc立马报incompatible pointer type告警:

test_void_ptr.c: In function ‘main’:
test_void_ptr.c:10:7: warning: passing argument 1 of ‘f’ from incompatible pointer type [-Wincompatible-pointer-types]f(h);^
test_void_ptr.c:5:6: note: expected ‘int **’ but argument is of type ‘handle {aka int *}’void f(handle *ph) {^

那能否统一用int*做handle来规避上述问题呢?恐怕不太行,因为函数接口将形参定义成void *就是为了方便调用者传参时不用进行强制类型转换,改成int*后,就必须强转了。

怎么解决?

我试了以下方法:

  1. voidtypedef成VOID以创造新的基类型,不好使
  2. handle *typedef成phandle以显式区别2种void指针类型,也不行

看样子只能程序员自己注意了?好悲催啊!
等等,有没有可能,编译器就是不想区分void*void **呢?毕竟指针本身就是可以值传递的,为什么还要脱裤子放屁地搞个二级指针呢?

更改编程习惯

回头看我们的库接口设计,是有问题的,create返回context的地址给调用者,那么调用者在destroy执行完毕后当然有义务将记录的context置空,但是库作者为了“易用性”,选择在destroy里自己置空,而这势必要获取调用者记录context地址的指针的地址,这就“越界”了!
正确的做法是destroy只销毁context,至于调用者可能忘记置空context指针导致的内存访问问题,由调用者自己操心

总结

  1. C语言中尽量不要使用void **参数
  2. 用户态逻辑尽量用C++来写,不能改的话,至少用C++编译器来编译吧。

相关内容

热门资讯

全球资本为何“链”上北京? 近日,2026中关村论坛年会期间,2026年投资北京大会举行。34个重大项目集中签约,总金额达619...
伊朗首都遭大规模袭击,以色列:... CCTV国际时讯  新华社据CCTV国际时讯,当地时间今天(3月28日)凌晨,伊朗首都德黑兰多地遭多...
4月7日开赛,最低票价48元!... 公众号转载太原发布稿件,须申请授权。3月27日,WTT(世界乒乓球职业大联盟)常规挑战赛太原站202...
亿纬锂能申请正极极片相关专利,... 3月28日消息,国家知识产权局信息显示,惠州亿纬锂能(维权)股份有限公司申请一项名为“一种正极极片及...
亿纬锂能申请负极片制备相关专利... 3月28日消息,国家知识产权局信息显示,惠州亿纬锂能(维权)股份有限公司申请一项名为“负极片及其制备...