标识符(函数名、变量名)的选择

 标识符的选择亦有学问。通常一个标识符是由多个英语单词、或常用缩略语、模块名的组合。通过下划线或大小写来分隔单词,读起来有时候就像一句话。
好的标识符名称能让读者一看就知道它的用途,我们称这样的标识符是自解释的。
初学编程的人习惯使用过于短小的标识符。写程序的人当时明白,看程序的人(过后包括他自己)却如读天书。如果仅仅是不好读但能保持正确性还不至于太坏,关键是过于短小的标识符最大的问题就是在一个大型程序中引发冲突。当然,如果能事先(链接的时候)发现冲突你应该幸庆;最糟糕的是链接的时候没有报错,在运行中程序莫名奇妙的崩溃了,可怜的你却无从下手。

文件:peacock/src/dvbc/mainflow/menu/EmailInfoMenu.c
作者:刘雪
版本:0 (问题出在import到CVS之前)

原来的版本是:
char *write[3] ={...};
更改后的版本是:
static char *write[3] ={...};

当时的情况是程序一调用printf就死,栈已经被破坏,gdb看不到更多信息,而且没有C库的源代码,很难debug。
最后是汇集了hisi和ITI的多位技术人员花了3天时间才得以最终定位。我认为这样的代价很不值得。

原因:
write是文件系统的标准函数,printf最终是通过write函数里面的系统调用来驱动linux内核的设备驱动模块进而操作设备文件(即硬件设备:串口)的。因为刘雪在软件中重新定义了write标识符为变量,结果是标准C库里面的write函数没有链接到最终的执行码中去,于是运行中一旦调到write函数则程序指针PC就从文本段jump到数据段,焉能不死?

修改后的版本通过static回避了冲突,死机的问题解决了,但是它是一个好的变量名吗?你能看出来它表示什么意义,用途何在?

另:
追根溯源,该项目的文件是从shark项目移植过来的。即shark/src/dvbc/mainflow/menu/EmailInfoMenu.c,版本是1.7或之前。
shark系统中为什么不死呢?因为shark里面没有用到文件系统模块,printf是直接调用串口的driver来工作的,故没有调用标准的write函数之需求。

WindRiver的vxWorks给我们一个很好的学习榜样,所有的全局函数都是以模块名来作为前缀的。
比如操作信号的semCreate, semTake, semGive;操作任务的taskSpawn, taskDelay, taskDelete, 等等。
这样,冲突的问题就避免了。
ipanel也有可借鉴的地方,如他们所有的外部API都是以公司名称作为前缀。

进阶的问题:
1)重定义了write变量为什么没有引发链接冲突?我们经常见到的链接冲突和本案的情况有什么不同?
2)如果以后你也碰到这样的情况,在浩如烟海的变量、函数、源文件中怎么去定位问题呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值