Vic*_*cky 17 c null harvard-architecture
我们本周在这里遇到了有趣的问题.
我们在C上使用哈佛架构嵌入式平台,该平台具有16位数据地址和32位代码地址.
使用函数指针时会出现此问题.如果你有像这样的代码
if (fp) fp();
Run Code Online (Sandbox Code Playgroud)
要么
if (fp != 0) fp();
Run Code Online (Sandbox Code Playgroud)
一切都好.
但是如果你有像这样的代码
if (fp != NULL) fp();
Run Code Online (Sandbox Code Playgroud)
然后,因为NULL定义为(void *) 0,编译器(在这种情况下为gcc)a)不警告,b)对函数指针进行16位比较而不是32位比较.只要你的函数指针没有发生在64k边界上,所以所有底部的16位都是0就很好.
目前我们有大量的代码包含对NULL的显式检查.它们中的大多数将是数据指针,但其中一些将是函数指针.快速grep != NULL或== NULL显示超过3000个结果,许多人通过手动检查.
那么,我们现在想要的也是
找到比较函数指针(但不是数据指针)的所有情况的方法(所以我们可以将它们与我们定义为32位0的FP_NULL进行比较),或者
以这样的方式重新定义NULL,以便它做正确的事情.
(或者,我想,更新我们的gcc端口以检测并正确处理这种情况).
我无法想到任何适用于1的方法.我能想到的唯一方法是将NULL重新定义为0函数指针,这对于绝大多数针对数据指针的比较来说都是非常浪费的.(32位比较是4条指令,16位比较是1条指令).
有什么想法或建议吗?
sch*_*hot 18
在我看来,最简单的方法就是更换所有出现NULL的0.这适用于函数指针(如你所说)和对象指针.
这是(2)将NULL重新定义为plain的变体0.
但是你无法比较函数指针的事实是你NULL的实现中的一个错误.C99指出,对象和函数指针都可以比较空指针常量,并且NULL应该扩展为此常量.
来自C-FAQ问题5.8的小增加:
问:对于函数指针,NULL是否有效?
答:是(但见问题4.13)
(void *) 0(回复R ..的评论).我相信使用函数指针和(void *) 0一起是明确定义的.在我的推理中,我将参考C99草案1256的部分,但不会引用大部分以保持其可读性.它也应该适用于C89.
0并将这种表达式转换(void *)为空指针常量.并且:"如果将空指针常量转换为指针类型,则保证将结果指针(称为空指针)与不同于指向任何对象或函数的指针进行比较."==和!=操作数(除其他)的指针操作数和空指针常量.对于这些:"如果一个操作数是指针而另一个是空指针常量,则空指针常量将转换为指针的类型."结论:在fp == (void *) 0,将空指针常量转换为类型fp.如果指向函数,则可以将该空指针与之进行比较fp并保证不相等fp.Assignment(=)有一个类似的子句,因此fp = (void *) 0;也是明确定义的C.