我们应该寻找说谎的代码吗?


9

这是指答案中的讨论和对该问题的评论:业界对文档的厌恶是什么?。答案声称“代码不能撒谎”,因此应该是定位位置,而不是文档位置。一些评论指出“代码可能存在”。双方都有真相,至少部分是由于文档处理的差劲和不适当。

我们是否应该寻找说谎的代码,并将其与任何现有文档进行比较?还是通常它是所需要做的事情的最佳来源?如果它是敏捷代码,那么它说谎的可能性较小,还是该代码根本不说谎?


1
您能否阐明“说谎”的含义?为了获得您的上下文,我们不必在另一个问题中引用评论。
user16764 2013年

@ user16764在不考虑其他主题的情况下,首先想到的是打手枪的C竞赛
Izkata 2013年

如果文档说代码应该执行foo,而代码则执行bar,这是否意味着bar是代码应该执行的操作?还是我们假设bar是正确的操作,因为我们从未阅读过文档,因为代码始终是正确的?
2013年

如果该代码已被接受为条形码,则说明该文档有误且已过时。但是,如果foo和bar紧密相关,并且用户没有注意到它不能按预期方式完全解决他们的问题,那么有关foo的文档也许是正确的?换句话说,代码真的是代码应该做的一切吗?
星期四

Answers:


9

用外行的话来说:

是的,您应该搜索撒谎的代码并说出真相。但是不能将其与文档进行比较。那将是一种检测谎言的方法。

有几种方法可以掩盖代码,我将仅提及其中几种:

  • 由于永远不会满足条件而永远不会运行的代码块。该代码使您了解它的功能。
  • 增加不必要的复杂性的代码在于问题的真正复杂性。
  • 没有命名约定的代码之所以存在,是因为它使您误认为它所做的事情与实际所做的不同。

越短,它越少。这是不言而喻的。

代码越简单,则代码越透明。因此,它的谎言更少。

奥术语法技巧很多。最好使用清晰的分步算法。他们撒谎。

一个好的静态代码分析工具可以帮助您找到隐藏的代码。

好的自动测试电池也可以迫使代码讲真话。


4
The shorter and terser the code is, the less it lies. It's self evident. 我几乎不会这么说。根据我的经验,代码越短越短,通常必须将代码隐藏在具有欺骗性的函数调用中,因此清除代码的机会就更多。
梅森·惠勒2013年

@MasonWheeler你是对的。我编辑了“简洁”部分。
TulainsCórdova2013年

我不相信“没有命名约定的代码所在”。这当然很糟糕,但是如果什么都没告诉你,怎么会说谎呢?“我不是在告诉你!” 固执地阻碍和提供信息,但不具有欺骗性。当然,“谎言”是存在命名约定的情况,但是使用的方式与代码的实际用法不匹配-例如,如果您使用的是匈牙利语(“ uck”!),但有时会p使用变量的前缀不是指针。
Steve314

2
实际上,您所建议的内容可能比用“谎言”更好地描述为“技巧”。诡辩术往往很冗长和复杂,因此很难发现逻辑上的缺陷,表面诡辩又充满自信,因此人们不敢质疑它看起来很愚蠢。
Steve314

另一个示例:更改基础语言或运行时属性的代码,例如,重新定义或掩盖原始行为。
JustinC

6

代码不能撒谎。

代码中的内容是您的程序当前正在执行的操作-无论使用什么文档,质量检查或客户说什么。特别是如果您的代码已经发布并且已经存在了一段时间,则不应忽略该预期行为。

该代码肯定是不正确的。它的命名或组织肯定会产生误导。它肯定是不可读的。

但是,如果您想了解代码在什么的真理源,而不是代码应该做的事情,不是代码旨在做的事情,而不是您认为代码正在做的事情……如果您需要知道代码实际上在做什么,转到代码。


有一种流派认为,如果您故意欺骗但在书呆子方面是正确的,那么您就不是在撒谎。这不是唯一的思想流派。例如,我有Aldert Vrij撰写的《侦破谎言和欺骗》的旧版本。这样做的第一件事就是考虑撒谎和欺骗的各种定义,选择包括学究正确但故意误导性的陈述,部分原因是因为无论如何这都是一种普遍的理解。
Steve314

抱歉,但是说“但它确实是正确的”并不意味着您不能被称为骗子-即使人们不反对,他们仍然知道。
Steve314

@ steve314-pssh。最初的问题是围绕评论。为这些罕见的场景而草率的做法是荒谬的,在这些场景中,代码被误导地使用,以进行辩论以支持注释(而忽略了通常的注释已过时的场景)。
Telastyn

1
我同意这一点-我不是在说你的观点,只是在做时使用的“谎言”的明显定义。代码可能在说谎-不是编译器,而是人类读者。在某些情况下,这甚至是一个故意的目标-诸如混淆不清的C竞赛之类的事情将是一个相对温和的例子。正如我在对user61852的评论中建议的那样,诡辩​​。仅仅因为编译器看过谎言并不意味着它不是谎言。
Steve314

@Telastyn我猜您从未使用过过滤器来进行重定向,从而导致逐步发生在空格上,然后进入未从该方法调用的代码,永不返回,对吗?上帝,我讨厌Java开发人员使用Java的!@#$。
Erik Reppen 2013年

0

你问几个问题。

我们应该注意说谎的代码吗?

当然!

我们应该将[代码]与任何现有文档进行比较吗?

尽管永远不会有任何伤害,尽管正如其他答案中提到的那样,这通常会导致您在文档中而不是代码中发现问题。

还是[code]通常是执行所需工作的最佳来源?

它始终所做工作的最佳来源。但是,代码应该做的最佳来源可以是(不同的)组合(主要是):

  • 代码本身;
  • 调用代码;
  • 该代码中的注释;
  • 文件;
  • 单元测试;
  • 整合和回归测试;
  • 程序员;
  • 最终用户;

哪个“最佳”来源(或其组合)取决于您的情况。

如果它是敏捷代码,那么它说谎的可能性较小,还是该代码根本不说谎?

我不确定“敏捷代码”是什么意思,AFAIK“敏捷”通常是指编码过程。假设您的意思是“在敏捷编程过程中创建的代码”,那么我可以肯定地说它仍然可以说谎。与在瀑布式项目中创建的代码相比,说谎的可能性是一个主观的问题(就我个人而言,我认为没有太大的联系)。


脚注
以上所有内容均基于可以存在代码的假设,并且这是一个基本的(尽管有些人为的)示例:

public int DivideByTwo(int input) 
{
    return input / 3;
}

这只是我会说“代码说谎”的一个示例,@ user61852还有其他一些示例(无法访问的代码,代码的复杂性与问题的复杂性不匹配,命名错误),而且我想还有更多示例。维基百科的谎言摘要相当不错,其中许多可以找到代码。

请注意,如果您与某人发生争执,请务必确保另一人的意思不是“代码不能说谎”,即“代码可以做到”。本质上,这里的另一个人使用“谎言”的定义进行定义,该定义是如此狭窄,以至于可以将“代码不能说谎”声明声明为公理/基本真理。在这种情况下,最好是同意他/她的公理。


0
if (x > 5) {
  doSomething();
} else {
  doADifferentThing();
}

您可以争论“谎言”一词在技术上是否适当,但此代码清楚地暗示着x 有时会大于5,有时不大于5。如果您查看整个程序,发现该函数只在一个位置调用过,并且x始终设置为常数6,那是个谎言。

而且,编译器可能已经注意到了这一点,并用简单的代码替换了这段代码

doSomething()

如果在程序的其他位置未调用doADifferentThing,则可能会将其完全从程序中删除。

如果您的语言支持assert某种在生产环境中已关闭的语言,则每个assert语句都可能是谎言。类型转换是另一个可能是谎言的断言。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.