防御性编码实践

lex*_*exu 16 coding-style

自从我第一次写作以来

if ($a = 5) {
   #  do something with $a, e.g.
   print "$a";
}
Run Code Online (Sandbox Code Playgroud)

并经历了正常的令人费解的会议

  • 为什么结果总是如此
  • 为什么$ a总是5

直到我意识到,我已经分配了5到$ a,而不是进行比较.

所以我决定把上面那种情况写成

 if (5 == $a)
Run Code Online (Sandbox Code Playgroud)

换一种说法:

如果您忘记添加第二个"="符号,则始终将常量值放在比较运算符的左侧,从而导致编译错误.

我倾向于称这种防御性编码,并倾向于认为它是防御性编程的表亲,而不是算法规模,而是关键词.

您开发了哪些防御性编码实践?


一周后:

对所有回答或可能在将来添加其他答案的人表示"谢谢".

不幸的是(或者说幸运的是!)没有一个正确的答案.为此,我的问题是广泛的,要求更多的意见或经验的学习,而不是事实.

小智 16

总是使用大括号:

if(boolean)
    oneliner();
nextLineOfCode();
Run Code Online (Sandbox Code Playgroud)

是不一样的:

if(boolean)
{
    oneliner();
}
nextLineOfCode();
Run Code Online (Sandbox Code Playgroud)

如果oneliner()是#defined函数,并且未定义,则下一行代码突然变为if().同样的事情适用于for循环等.使用大括号,下一段代码永远不会无意中成为条件if/for等.


Jar*_*Par 14

我采用的前三种防御性编码方法是

  1. 单元测试
  2. 单元测试
  3. 单元测试

对于代码质量而言,没有比用于支持您的良好单元测试更好的防御.

  • 在许多情况下,在实施之前编写单元测试.是的,这是一种编码实践. (4认同)

Tor*_*ørn 13

这是一个简单明了的,但我从来没有永远不会在我的代码中重复两次相同的字符串常量,因为我知道如果我这样做,我将拼写其中一个错误:)使用常量,人!


PW.*_*PW. 8

总是在if/for/while之后加上大括号......即使后面只有一个单句.BTW D. Crockford认为它也更好:必需的块


Tob*_*lte 8

将字符串与常量进行比较时,请写入

if ("blah".equals(value)){}
Run Code Online (Sandbox Code Playgroud)

代替

if (value.equals("blah")){}
Run Code Online (Sandbox Code Playgroud)

防止NullPointerException.但这是我唯一一次使用建议的编码风格(原因是"if(a = 1)..."在Java中是不可能的).


Jam*_*hes 7

我在Javascript世界中总是试图记住的一件事就是始终在与返回关键字相同的行上启动函数的返回值.

function one(){
    return {
        result:"result"
    };
}

function two(){
    return 
    {
        result:"result"
    };
}
Run Code Online (Sandbox Code Playgroud)

这两个函数不会返回相同的值.第一个函数将返回一个Object,其属性结果设置为"result".第二个函数将返回undefined.这是一个非常简单的错误,它的发生是因为Javascript过于热心的半结肠插入策略.在Javascript中,半冒号是半可选的,因此Javascript引擎会添加它认为应该是的半库存.因为return实际上是一个有效的语句,所以在return语句之后会插入一个分号,并且该函数的其余部分将基本上被忽略.

  • Javascript是邪恶的另一个原因. (4认同)
  • 我非常不同意.我认为它被赶到了市场,没有时间在实验室进行改进.它的人口爆炸,这意味着它不能在不破坏东西的情况下修复.正确使用它是一种出色的自适应和强大的语言.咆哮. (2认同)

Aar*_*lla 6

来自我的博客:

  1. 积极思考并尽早返回并避免深度嵌套.代替

    if(value!= null){...做一些有价值的东西}}返回

    if(value == null){return} ...做一些有价值的事情......

  2. 避免使用"字符串常量"(即多个位置的引号中的相同文本).始终定义一个实常数(使用名称和可选注释含义)并使用它.


Tom*_*rta 5

  • 始终初始化变量
  • 使用const的地方我可以(不使用mutable)
  • 避免裸动态分配内存或其他资源
  • 始终使用花括号
  • 在编码实现之前对任何类的代码用例和测试
  • 尽可能多地打开有用的警告(-Wall -Wextra -ansi -pedantic -Werror至少)
  • 使用解决问题的最简单的工具(在我目前的环境中,那是bash- > grep- > awk - > Python - > C++).


Tal*_*Tal 5

就个人而言,我不喜欢这种防御风格,它使代码难以阅读.

VC编译器警告级别4将发现此(可能)错误.
"警告C4706:条件表达式中的赋值"

您可以在任何级别启用此特定编译器警告:

#pragma warning(3,4706)
Run Code Online (Sandbox Code Playgroud)