自从我第一次写作以来
if ($a = 5) { # do something with $a, e.g. print "$a"; }
并经历了正常的令人费解的会议
为什么结果总是如此
为什么$ a总是5
直到我意识到,我已经分配了5到$ a,而不是进行比较.
所以我决定把上面那种情况写成
if (5 == $a)
换一种说法:
如果您忘记添加第二个"="符号,则始终将常量值放在比较运算符的左侧,从而导致编译错误.
我倾向于称这种防御性编码,并倾向于认为它是防御性编程的表亲,而不是算法规模,而是关键词.
您开发了哪些防御性编码实践?
一周后:
对所有回答或可能在将来添加其他答案的人表示"谢谢".
不幸的是(或者说幸运的是!)没有一个正确的答案.为此,我的问题是广泛的,要求更多的意见或经验的学习,而不是事实.
总是使用大括号:
if(boolean) oneliner(); nextLineOfCode();
是不一样的:
if(boolean) { oneliner(); } nextLineOfCode();
如果oneliner()是#defined函数,并且未定义,则下一行代码突然变为if().同样的事情适用于for循环等.使用大括号,下一段代码永远不会无意中成为条件if/for等.
我采用的前三种防御性编码方法是
单元测试
单元测试
单元测试
对于代码质量而言,没有比用于支持您的良好单元测试更好的防御.
这是一个简单明了的,但我从来没有永远不会在我的代码中重复两次相同的字符串常量,因为我知道如果我这样做,我将拼写其中一个错误:)使用常量,人!
总是在if/for/while之后加上大括号......即使后面只有一个单句.BTW D. Crockford认为它也更好:必需的块
将字符串与常量进行比较时,请写入
if ("blah".equals(value)){}
代替
if (value.equals("blah")){}
防止NullPointerException.但这是我唯一一次使用建议的编码风格(原因是"if(a = 1)..."在Java中是不可能的).
我在Javascript世界中总是试图记住的一件事就是始终在与返回关键字相同的行上启动函数的返回值.
function one(){ return { result:"result" }; } function two(){ return { result:"result" }; }
这两个函数不会返回相同的值.第一个函数将返回一个Object,其属性结果设置为"result".第二个函数将返回undefined
.这是一个非常简单的错误,它的发生是因为Javascript过于热心的半结肠插入策略.在Javascript中,半冒号是半可选的,因此Javascript引擎会添加它认为应该是的半库存.因为return
实际上是一个有效的语句,所以在return语句之后会插入一个分号,并且该函数的其余部分将基本上被忽略.
来自我的博客:
积极思考并尽早返回并避免深度嵌套.代替
if(value!= null){...做一些有价值的东西}}返回
写
if(value == null){return} ...做一些有价值的事情......
避免使用"字符串常量"(即多个位置的引号中的相同文本).始终定义一个实常数(使用名称和可选注释含义)并使用它.
始终初始化变量
使用const
的地方我可以(不使用mutable
)
避免裸动态分配内存或其他资源
始终使用花括号
在编码实现之前对任何类的代码用例和测试
尽可能多地打开有用的警告(-Wall -Wextra -ansi -pedantic -Werror
至少)
使用解决问题的最简单的工具(在我目前的环境中,那是bash
- > grep
- > awk - > Python - > C++).
就个人而言,我不喜欢这种防御风格,它使代码难以阅读.
VC编译器警告级别4将发现此(可能)错误.
"警告C4706:条件表达式中的赋值"
您可以在任何级别启用此特定编译器警告:
#pragma warning(3,4706)