也谈C语言标识符的NAMESPACE

P.J Plauger的"The Standard C Library"一书的Chapter0的章后练习中有这样的一道题:编写一个包含如下一行语句的正确的程序:
x:      ((struct x*)x)->x=x(5);
并描述这行语句中x的5种截然不同的use,这里其实涉及到这么一个知识或者说概念:C语言的命名空间(namespace),在"C语言参考手册"中还被称作: overloading class。

这里namespace,并非C++中的那个keyword "namespace",这里的namespace更多是编译器为了识别不同范围下的标识符而进行的划分,而不是提供给应用程序员的类似c++中的那个namespace facility。再次注意:C的namespace不是一个关键字。

简单分析一下这行语句:x:      ((struct x*)x)->x=x(5);
这里有5个x,第一印象:这样的语句能编译过去么?那既然P.J Plauger提出了这样的问题,那么自然有solution。
从左到右顺序:
第一个x — 毋庸置疑,这是一个标号(label) ;
第二个x — 这里的x显然是一个struct tag(结构体标志);
第三个x — 这里的x 无法确定其具体身份,可能是一指针类型,也可能就是一个整型;
第四个x — x前面有->,显然这个x是某结构体的一个成员变量;
第五个x — x(5)让人"浮想联翩",第一印象是函数调用,细致一想还可能是一个宏哦(你肯定会说不可能,呵呵,别着急,慢慢来)

到底如何增加一些语法元素能让这一行能顺利通过编译,并执行后得到合理结果呢?我们不妨先来温习一下C标准中对C的"命名空间"的诠释。

在"C语言参考手册"中有如此说明,标准C将其Namespace分成了五种,分别是:
1) 预处理器宏名
2) 语句标号
3) 结构、枚举、联合结构的标志
4) 成员名
5) 其他名称 包括变量名、函数名、typedef名称和枚举常量

有了以上的说明,我们有了第一种方案:
上面说了,语句x:      ((struct x*)x)->x=x(5)中有三个x都是可以确定的,不确定的是第三个x和最后一个x。我们先考虑让最后一个x为一个函数。

考虑到最后一个名称空间的说明,一旦最后一个x为函数的话,第三个x就不能为变量名、typedef名称和枚举常量了。如果x是对象宏(不带参数的宏),显然也不合理;那么我们先将x实现为函数看看:
struct x { //for the 2nd x
        int x;  //for the 4th x
};

int x(int a) { //for the 3rd and 5th x
        return a;
}

int main() {
x:      ((struct x*)x)->x=x(5);
}
这个在gcc(sunos or mingw on windows下)下编译能顺利通过。但是执行一下编译出的程序,会出现致命错误。初略分析一下也不奇怪。函数x的地址是在代码段,那块内存区域是只读且受保护的,尝试强制赋值显然os是不允许的。

第一种方案虽然能通过编译,但是执行结果不合理。我们来做第二种尝试:试着将最后一个x实现为一个函数宏(带参数的宏)。
struct x { //for the 2nd x
        int x;  //for the 4th x
};

struct x ax;

#define x(a)  (a);

int main() {
        int x = (int)(&ax);
x:      ((struct x*)x)->x=x(5);  
        printf("%d\n", ((struct x*)x)->x); //output: 5
}
这回,我们得到了正确的且合理的solution了。在P.J Plauger的"The Standard C Library"一书中还有一张关于C语言命名空间的图,记起来更形象。

关注四川汶川地震,为灾区人民祈祷

时间定格在公元2008年5月12日,那天是星期一,工薪族们正努力的从周末休假状态转换到工作状态;操场上正在嬉戏打闹的低年级的小学生听到铃声陆续进入教室准备上课;初三、高三的莘莘学子们正伏案刻苦的读书,准备迎接即将来临的中考和高考;幼儿园里孩儿童们依旧在老师的看护下午睡着;盘山公路上、景区的缆车上,兴致勃勃的游客们正在欣赏着大自然的美丽景色。就当人们沉浸在这美好、恬静生活的时候,地球的内部,更精确的说是处于北纬31度,东经103.4度位置的美丽的四川汶川地区下面的地球板块迫于其他板块的压迫发生了运动,地震发生了。

这次地震波及范围之广实属罕见,除了吉林和黑龙江没有探测到震级外,其他省和地区均有震情报告。灾难面前的中国人民向来是团结一致、众志成城的。食品、药品、棉被、帐篷、照明设施、救灾款项源源不断的送往灾区。如果不是汶川地区地形复杂,道路封闭,更多的人将会会得到重生的机会。

这次地震后的救援有几大特点:
1) 政府反应极其迅速,各种预案立即启动,为灾后救援提供了宝贵的时间。值得一提的是:在震后的2个小时左右温总理就已经坐在了飞往震区的飞机上了。
2) 各大媒体第一时间滚动持续传递震区消息,辟谣以正视听,让老百姓及时了解震区情况,以正确配合救灾工作。
3) 灾区人民自救得力。在没有救援人员到达的情况下,灾区幸存的人们自发组织进行救援,很多人因此得到及时救援,得以重生。

这次地震还有几个疑点,值得震后反思和事后算账:
1) 学校教学楼和宿舍楼损毁严重,这里难道没有人为的因素么?政府应在震后进行取证调查,让那些在此次灾难中逝去的孩子们、老师们以及他们的亲属可以得到慰藉;
2) 通信设备损毁严重,通讯不畅,影响救援。在年初的南方雪灾中,也出现了类似的情况,这很值得反思,电信、移动、联通在建立基站、铺设线缆时是否给予充分设计、论证?是否考虑到不同地区的不同环境情况而做到因地制宜了。

一个想法:
震后,由于道路补偿,救援人员不能及时赶到,而劫后余生的人们在自救的过程中却因没有得力的和专业的救援工具而导致救援缓慢。我想国家是否可以做这样一件事:在全国地质灾害多发地区,设置多个公共救援工具存放处,而不是像目前都放到大城市的集中的储备库中。这样一旦发生灾情,大家可以就近拿到工具,节省时间。另外我们应该向邻国日本学习,定期对国民进行灾难教育,让国民了解自救以及救人的基本技能,或者在教育课程中,加入必要的自救和互救的实习课程,学习知识、工具使用,就好比大学新生必须进行的军训一样,让大家都掌握自救和互救的技能。如果能确实做到未雨绸缪,那么灾难给我们带来的损失将会降低很多,更多的人能生存下去。

这次汶川地震不禁让我想起了1975年家乡发生的那场地震,与汶川地震不同的是,那次地震被准确的预报出来了,这大大减少了人员伤亡和财产损失。试想如果汶川地震事先有预报,那些孩子们无论如何都不会有如此大的伤亡的。遗憾的是这次地震,事前没有任何预测,正如本文开头所描述的,灾难是突然降临的,人们没有丝毫准备。

现在距离地震发生的时间已经过去了50多个小时了,我们现在能做的就是力所能及的捐钱捐物,并为灾区那些依旧掩埋在废墟中的人们祈祷,祈祷他们能早日获救,得以重生。

让我们一起来祈祷吧!

突然萌生出一个幼稚的想法:转行做地震预报研究去!

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! Go语言第一课 Go语言精进之路1 Go语言精进之路2 Go语言编程指南
商务合作请联系bigwhite.cn AT aliyun.com

欢迎使用邮件订阅我的博客

输入邮箱订阅本站,只要有新文章发布,就会第一时间发送邮件通知你哦!

这里是 Tony Bai的个人Blog,欢迎访问、订阅和留言! 订阅Feed请点击上面图片

如果您觉得这里的文章对您有帮助,请扫描上方二维码进行捐赠 ,加油后的Tony Bai将会为您呈现更多精彩的文章,谢谢!

如果您希望通过微信捐赠,请用微信客户端扫描下方赞赏码:

如果您希望通过比特币或以太币捐赠,可以扫描下方二维码:

比特币:

以太币:

如果您喜欢通过微信浏览本站内容,可以扫描下方二维码,订阅本站官方微信订阅号“iamtonybai”;点击二维码,可直达本人官方微博主页^_^:
本站Powered by Digital Ocean VPS。
选择Digital Ocean VPS主机,即可获得10美元现金充值,可 免费使用两个月哟! 著名主机提供商Linode 10$优惠码:linode10,在 这里注册即可免费获 得。阿里云推荐码: 1WFZ0V立享9折!


View Tony Bai's profile on LinkedIn
DigitalOcean Referral Badge

文章

评论

  • 正在加载...

分类

标签

归档



View My Stats