C语言中“少做之过”,案例分析

        属于“少做之过”的特性就是语言应该提供但未能提供的特性,如标准参数处理以及把lint 程序错误地从编译器中分离出来。
用户名中若有字母f,便不能收到邮件
        这个 Bug 报告非常令人困惑。它声称“如果用户名的第二个字母是 f,该用户就无法收到邮件”,听起来真是难以置信。不能收到邮件跟用户名中的某个字母又有什么关系呢?无论如何,用户名中的字母与那件传送过程并没有什么联系啊!然而,这个问题出现在许多地方经过一番紧张的测试后,我们发现如果用户名的第二个字母是 f,邮件确实无法发送到他们那里!就是说,Fred 和 Muffy 可以收到邮件,但 Effie 却无法收到。对源代码进行检查后,我们迅速发现了问题,所在。
许多人对ANSIC采用argcargv 的约定向 C程序传递参数感到惊奇但事实就是如此UNIX 的约定又有所提升,达到了一个标准的层次,但此时却成了这个邮件 Bug 的原因之一这个 mail 程序在先前的版本中被修改成这么一个样子:

if(argv[argc-1][0] == '-' || (argv[argc-2][1] == 'f'))
    readmail(argc,argv);
else
    sendmail(argc,argv);

        运行 mail 程序时,它既可以发送邮件,也可以读取到达的邮件。让一个程序负责两项截然不同的任务有何意义,我们暂时不必细究。这段代码的目的是:查看参数,根据它的内容决定到底是读取邮件还是发送邮件。它的分析方法有点像试探法:先寻找能确定读取或发送的选项开关。在这里,如果最后一个参数是选项开关(也就是以--个连字符开头),就可以确定是读取邮件。如果最后一个参数并不是选项开关而是文件名,并且倒数第一个参数是“f程序也是执行读取邮件的操作。
这就是程序员步入歧路的开始,C 语言中支持的乏又推了他一把。那个程序员只是看了一下倒数第二个选项的第二个字符,如果它是一个“f”,他就是认为 mail 程序是被类似下面的命令所调用:

mail -h -d -f /usr/linden/mymailbox


        在绝大多数情况下这是正确的,邮件可以从 mymaibox 中读取。也有可能发生下面这种情况:

mail effie Robert


在这种情况下,mail 序的参数处理过程便认为应该读取邮件而不是发送。瞧!发送到第二个字母为“f”的用户的 E-mail 不见了!要修正这个 Bug 非常简单:当查看倒数第二个参数寻找可能出现的“f”时,确定在它前面的是一个连字符:
 

if(argv[argc-1][0] == '-' && (argv[argc-2][1] == 'f'))
    readmail(argc,argv);
else
    sendmail(argc,argv);

        这个问题是由于对参数的糟糕解析所引起的,但选项开关和文件名之间分类不清也是原因之一。许多操作系统(如 VAX/VMS)能够在程序中区分运行时选项和其他参数(如文件名),但UNIX 却不能,ANSIC也不能。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值