C语言传入错误大小数组到函数时强制触发编译告警的方案是否安全?
结论先行:你的方案完全安全,不属于未定义行为,完全可以正常使用。
原理说明
- 指针合法性依据
char (*arg)[8]是指向长度为8的char数组的指针,C标准明确规定:数组的内存起始地址,和数组首元素的内存起始地址数值完全一致,仅指针类型不同。因此两种获取char*指针的写法均合法:
- 你写的强制转换写法:
char *tmp = (char*) arg;符合标准,没有问题 - 更直观的无转换写法:
char *tmp = *arg;直接解引用数组指针拿到首元素指针,不需要强制类型转换,可读性更高,更推荐使用。
- 无未定义行为的依据
原foo函数接收char*参数,操作的是单个char类型数据,通过上述方式得到的指针指向的是合法的char数组内存,完全符合C语言的别名规则,不会出现越界、非法访问类的未定义行为,你实测的运行结果和编译表现也符合预期。
方案优势
你选择的数组指针方案,是纯C语言下不需要依赖结构体就能实现编译期严格检查数组长度正好为指定值的最优方案:
- 传入长度不匹配的数组时,编译器会直接抛出指针类型不兼容的告警/错误,完全满足你的需求
- 对原有业务逻辑侵入极低:如果用封装方案,不需要修改原
foo的任何代码;如果直接改写原函数,只需要在函数开头加一行char *arg = *argaux;即可复用所有原有逻辑。
补充注意点
如果后续需要适配不同长度的数组,也可以用宏封装生成对应长度的检查函数,不过针对你当前固定长度为8的场景,现有方案已经完全够用。
内容的提问来源于stack exchange,提问作者klutt
相关产品推荐
相关产品推荐

