为什么Cert-C禁止在while循环声明中进行分配?

时间:2018-08-22 21:30:23

标签: c

说我想遍历C语言中的一个列表。有两种常用的方法。

/* method a */
while (ptr = ptr->next) { /* do stuff */ }

/* method b */
ptr = head;
while (ptr) { /* do stuff */ ptr = ptr->next; }

CERT-C bans method A。为什么是这样?当然,B需要更多的手动编码来记住在所有可能的循环点处进行迭代(如果函数无效,则该函数可能需要continue经过某些节点),并且方法A保证了一致的迭代。

1 个答案:

答案 0 :(得分:2)

使用=运算符的赋值可以容易地与相等性==运算符混淆。这部分文字清楚地表明了这一点:

  

尽管代码的目的可能是将b分配给a并测试结果等于0的值,但程序员经常错误地使用这种情况赋值运算符=而不是等于运算符==

我同意在while循环的情况下-您希望每个循环都包含下一个元素-对于有成就的编码人员,惊喜元素实际上并不存在。对于新编码员,可能仍然会犯错。他们要么将分配误认为是测试相等性,要么不直接看到表达式的结果何时为0


我会确保将表达式写成while (ptr != NULL),因为这样可以使意图最明确,并且表达式没有任何副作用。如果您确实允许选择语句中有单一副作用,则可以使用while ((ptr = ptr->next) != NULL)(我自己更喜欢术语“流控制语句”,但这更像Java)。

我本人要远离while ((ptr = ptr->next))中的附加括号,因为这可能会误认为是草率的,并且代码美化程序可能会针对不必要的括号发出警告。