标签 博客 下的文章

P.J.Plauger版本C标准库实现分析之'assert.h'

I believe that seeing a realistic implementation of the Standard C library can help you better understand how to use it.
                                                                                  — P.J.Plauger

按照字母序首先我们来看看<assert.h>,这个文件提供的接口功能很简单,但却是我们极其常用的功能-断言机制(如果条件为False,则输出Diagnostics信息,然后Abort)。当然在最终产品中使用断言并不是一种好的方法,不过断言是一种很有用的帮助我们调试程序的好工具。

我们一般在程序的调试版本中使用断言机制,一般用来对Input进行Validation,输出一些Diagnostics信息。如:
assert((idx > 10) && (idx < 100));

<assert.h>中提供一个宏assert,这个宏的功能由另一个宏NDEBUG(标志是否是DEBUG版本)决定。如果NDEBUG宏在你include <assert.h>时没有被定义,这时断言功能开启;否则断言功能关闭。如:

#define NDEBUG
#include <assert.h> /* 此时断言功能关闭 */

你也大可不必在你的各个源文件中控制断言功能的开关,在编译器选项中同样可以定义NDEBUG宏,如gcc -DNDEBUG test.c,当然对于大的project,这些是应该放在Makefile中的,这样的结果就相当于在你所有#include <assert.h>的地方之前定义了NDEBUG宏,也就是说在每个编译单元中,断言功能都是关闭的。

assert宏看起来很简单,但是由于其是C标准库提供的接口,所以在实现的时候需要考虑的更加细致和全面一些。从上面的叙述上来看assert.h文件的结构应该大致如下:
#undef assert
#ifdef NDEBUG
#define assert(test) ((void)0)
#else
#define assert(test) …
#endif

我们可以很轻松的就拿出一个assert的实现版本:
/* NDEBUG not defined */
#define assert(test) if (!(test)) \
 fprintf(stderr, "Assertion Failed: %s, file %s, line %d\n", \
 #test, __FILE__, __LINE__); \

那么这个版本的实现可以接受不,答案是不能。原因有以下几点:
1) 这个实现中直接用到了stderr和fprintf,这两个符号都是在<stdio.h>中声明的,但是C标准库头文件基本上都是各自独立的,在<assert.h>中是不会再包含其他头文件的,那么这就要求使用assert的程序自己包含<stdio.h>,这显然不符合一个C标准库的基本要求;
2) assert宏应该最终展开为一个void expression,因为用户很可能在他们的程序中写出像(assert(0 < x), x < y)这样的代码来,而在上面的实现版本中,显然assert展开后不是一个void expression。

我们再来看看P.J.Plauger的实现版本:
/* NDEBUG not defined */
void _Assert(char *);
#define _STR(x) _VAL(x)
#define _VAL(x) #x
 
#define assert(test) (test) ? (void)0 \
 : _Assert(__FILE__ ":" _STR(__LINE__) " " #test)

/* in xassert.c */
#include <assert.h>
#include <stdio.h>

void _Assert(char *msg) {
 fprintf(stderr, "%s — assertion failed\n", msg);
 abort();
}
 
分析一下这一版本的实现,首先assert宏并没有直接调用任何库输出函数,而是调用了一个自己实现的函数_Assert,把向stderr输出诊断信息的活都交给了_Assert。_STR和_VAL是两个辅助宏,用来将__LINE__字符串化。这里比较难懂的地方就是_Assert(__FILE__ ":" _STR(__LINE__) " " #test)这一句,其实这个也很好理解。看看下面语句的执行结果:
printf("%s\n", "Hello" " " "Tony!");
执行上面语句你会看到Hello Tony!,这样一来实际上_Assert(__FILE__ ":" _STR(__LINE__) " " #test)就可以被理解为:
_Assert("THE_FILENAME_STRING" ":" "THE_LINE_STRING" " " "THE_TEST_STRING")

英语培训日记20060707

这是自从大学毕业以来第一次连续上五天课,第一感觉就是疲倦,甚至比上班还要累。也许会有人说我"身在福中不知福",也许吧。看着大连软件园周围那些匆匆忙忙的年轻人的身影,也许我的确该感到'幸福'。

今天是商务英语写作课的第一节,老师也安排从最基础的Business Letter开始。其实说到英语信函,很多人会记得在初中英语教材中就有涉及,只是当时老师不会讲的如此之细,侧重点也不同罢了。如何能写出'good business letter'呢?这里老师介绍了七个关键点,也叫'7C'原则。哪'7C'呢?
. Clearness
. Conciseness
. Courtesy
. Consideration
. Concreteness
. Correctness
. Completence

记得在以前的一次商务英语写作中也谈到过这'7C'原则了。至于这'7C'原则的具体细节,有些烦琐,不说也罢,总而言之,言而总之,在写Business Letter的时候,尽量用短句清晰的表达你的想法,注意谦恭礼貌,尽量从对方的角度考虑问题,多用'You' Attitude,少用'I/We' Attitude。

现在使用的商业信函的style有两种,一种叫'Semi-Indented Style',一种叫'Blocked Letter Style';前一种的格式如下:
Dear xxx,

    xxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.

    xxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
                   
                    Yours sincerely
                    your_name
                    your_position
                    your_company

后一种Blocked Style的格式更为被现代人接受,其样式如下:

Dear xxx,

xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxx.

xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxx.

Yours sincerely
your_name
your_position
your company

同样商业Email的书写与此相同。当然传统信函的书写原不止这么简单,我们还要考虑到letter-head, Date等等在称呼前面的内容,因为平时基本不会用到这种信函(大多数都用Email),所以这里不再介绍了。学习商务信函写作的一个很好的办法就是学习你的外国客户写给你的信函,模仿它们,准保没错。

三四节的口语,Alex给我们带来了Salvador Dali的一些surealism的名画,让我们其中一个人描述画中的事物,其他两个人在黑板上根据听到的内容Draw the picture. 我们玩的不亦乐乎!当然再这个活动结束后,Alex给我们解释了要这么做的原因:当你和客户沟通的时候,你怎样来有效的describe一种事物才能让你的客户理解的和你描述的吻合得更好而不是'张冠李戴'呢,从你describe一幅画给别人的过程中,你就可以总结出来。Take a shot!

如发现本站页面被黑,比如:挂载广告、挖矿等恶意代码,请朋友们及时联系我。十分感谢! 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