首页
社区
课程
招聘
[翻译]关于C++编程的42条建议(三)
发表于: 2017-3-4 17:38 3910

[翻译]关于C++编程的42条建议(三)

2017-3-4 17:38
3910


让我们继续讨论和文件有关的话题,再来看EOF。但这次我们要讨论的是完全不同的bug类型。它通常只出现在本地化软件版本里。

下面的代码片段是选自Computational Network Toolkit错误被PVS-Studio诊断为:V739 EOF不应该和char类型比较。‘c’应该是int类型。

解释

让我们来看EOF是怎样声明的:


如你所见,EOF就是一个值为‘-1’int类型。Fgetc()返回一个int类型的值。也就是说,它可以返回0255的一个数,或者是-1EOF)。

使用扩展字符集(Extended ASCII Codes)的用户在程序中某一个字母处理不当的时候可能会出错。

比如说,在Windows1251编码表中,俄文的最后一个字母是0xFF ,而在程序中就会被编译为文件终止符。

正确代码

建议

在这里并没有什么特殊的建议,但既然我们谈到了EOF,我想展示一些人没有注意到的比较有趣的错误。

只要记住,如果一个函数的返回值是int类型,就不要急于把它转化为char类型。停下来检查看有没有错。顺便提一句,我们在第二个技巧“大于0并不意味着是1”那里讨论memcmp()函数的时候用到了相似的代码。(关于MySQL漏洞那一块)。

下面的代码来自TortoiseGIT项目。该错误被PVS-Studio诊断为:V665 也许,在此处,‘#pragma warning(default: X)'用得不对。应该用'#pragma warning(push/pop)'


解释

程序员经常认为,早期让警告实现的"pragma warning(disable: X)"指令在使用"pragma warning(default : X)"后就能继续工作。但并非如此。'pragma warning(default : X)'这条指令是把‘X’警告设置为DEFAULT状态,这两个不是同一件事。

假设一个文件在编译时用了-wall,那么就会出现C4061警告。如果你增加了"#pragma warning(default : 4061)" 指令,那么这条警告就不会出现,因为它已经被默认关掉了。

正确代码


建议

返回警告的之前状态的正确方法是使用"#pragma warning(push[ ,n ])" "#pragma warning(pop)"这两条指令。可以看Visual C++11关于这些指令描述的文档:: Pragma Directives. Warnings.

库开发者应该要特别注意V665警告。忽视定制警告会在库使用者这边引起巨大的灾难。

关于这个话题的,值得一看的好文章:So, You Want to Suppress This Warning in Visual C++

下面的代码来自OpenSSL库。错误被PVS-Studio诊断为:V666 检查‘strncmp’的第三个参数。它可能和字符串的长度不一致,字符串长度取决于第二个参数。


解释

很难停止使用魔数。而且没有理由不使用类似0, 1, -1, 10这些常数。更难的是,给这些常数命名,而且,它们会使阅读代码变得更复杂。

然而,减少使用魔数的个数是有用的。比如说,避免使用用来定义字符串长度的魔数就很有用。

让我们来看一下上面给出的代码。代码看上去很像是复制粘贴的。程序员复制了下面这一行:

之后,用"BITLIST"代替"HEX" ,但是程序员忘了把3改为7. 结果就是,字符串不是和"BITLIST"做比较,而是仅仅比较了"BIT"。这个错误似乎不太严重,但终究是个错误。

用复制粘贴来写代码真的很糟糕。更严重的是,字符串长度由魔数来定义。一直以来,我们遇到这样的错误,就是字符串长度和确定的数字不一致的错误,都是因为拼写错误或者程序员的疏忽。所以,这是一个典型的错误,我们需要做点什么来避免它。让我们来看看应该如何避免。

正确代码

乍一看,只要把strncmp()换成strcmp()就好了。那样魔数就消失了。

不好——我们改变了代码运作的逻辑。strncmp()的作用是检查一个字符串是否是以‘HEX’开始的,而strcmp()是检查两个字符串是否相等的。它们做的是不同的检查。

要解决这个问题最简单的方法就是改变常数:

这个代码是正确的,但是魔数7还在那里,这就有点不好了。这也是为什么我要建议另一种方法。

建议

如果我们能够正确估计字符串的长度,这样的错误就能够避免。最简单的方法就是用strlen()函数。

在下面例子中,如果你忘记更改字符串,你能更快地发现它们的不匹配。

但是这个建议有两个缺点:


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 1
支持
分享
最新回复 (2)
雪    币: 47147
活跃值: (20450)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
2
辛苦了
2017-3-4 17:55
0
雪    币: 175
活跃值: (2531)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
写的很好,学习。
2017-3-4 18:00
0
游客
登录 | 注册 方可回帖
返回
//