编写无效代码有用吗?


16

您觉得编写无效代码有用吗?

有人说:“如果您有2种逻辑来执行某些操作,则不要使其他逻辑代码成为注释或删除代码,而使其成为无效代码,因为这不会影响该操作。”

例:-

if(true){
    // logic - 1
} else {
    // logic - 2  // dead code
}

是真的吗


我通常不编写无效代码,而只是删除第二个逻辑。


6
为什么使它变得复杂。只需将其删除,只需KISS
Jigar Joshi

1
我不明白要点...
Phil

13
我不想让程序做很多事情。您如何决定在else分支中放入什么?
保罗·布彻

4
我之前曾用过它来测试部分代码,这些代码在正常操作中很难设计出一条路线(然后将条件改回发布),但是我从一开始就故意编写此代码看不到任何好处:-它会使读者感到困惑,它会使代码膨胀,并且绝对不会加快代码的速度!
马特·威尔科

1
只是说明代码不是存储过去的代码更改的地方。这就是源代码管理的目的。
funkymushroom 2011年

Answers:


67

海事组织,这比没有意义还糟。

除了浪费时间,它还给您(或下一个家伙)一种幻觉,即您拥有一些可以更改true为的代码false。这只是一种错觉...除非您对其进行测试。

当然,如果是这样,则会使代码更难以阅读。


7
+1代表“比无意义更糟糕”。这是一个等待发生的错误。它在不需要的地方增加了复杂性。花费更多的时间来了解代码。
Dietbuddha 2011年

13

如果使用任何形式的SCM死代码,则几乎没有用。您应该改为删除它,并且如果您需要查看逻辑2的代码,则可以从SCM存储库中检索它。

编辑:

如果您有死代码并正在维护代码的其他部分,则可以尝试获取某些代码的用法,这可能会增加死代码。如果其他人在进行维护,他们可能不知道它实际上是无效的代码,即使这样做,他们也肯定不知道为什么它仍然存在。

如果随后您发现一个方法可以删除,因为“实时”代码不使用该方法,而仅死代码使用该方法,则您必须更改(很可能破坏)您的死代码,或者使另一个方法本身成为死代码。

最后,您肯定会以某种形式的维护陷入困境。

因此,最好的代码是删除的代码,因为它不会产生错误的结果或分散维护者的注意力。:)


但是,您如何知道它存在于存储库中?
Michael Borgwardt

@Michael通常您有存储库注释或某种文档,可以在其中提示该代码的存在。
托马斯,

8

不,那是不好的,因为它会使您的代码混乱并降低可维护性。

通常,有明显的理由倾向于使用替代“逻辑”之一。此原因(以及存在被拒绝的替代方法)应记录在代码注释中。万一原因变得无效,则可以从存储库历史记录中检索替代代码(如果以前是首选的,已实现的解决方案),也可以使用当前的全部知识和要求充实和实施替代代码(如果只是模糊的话)理念)。


4

它不会影响操作,但会影响维护。您希望使代码尽可能整洁,以便于维护。


4

老实说,我对你在做什么感到困惑。

按优先级降序排列:

  1. 您应该在某个地方记录代码更改以便在新代码不起作用时可以进行比较。这应该始终在源代码管理中。我认为您已经这样做了。如果没有,请尽一切可能获取某些形式的源代码管理。如果您绝对需要这样做(而且我一生中从未听说过这是个好主意),那么至少可以随时对源状态进行定期备份。

  2. 假设您正在执行#1,因此您可以在需要时恢复无效代码,请不要长期将其保存在活动代码中。这只会造成混乱,增加无价值的额外复杂性,需要维护,与实时代码不同步并在将来误导人们,等等。

  3. 也就是说,在某些特定情况下,两个代码路径之间的编译时切换是合理的。在开发新代码时以及紧随其后的时候,同时拥有这两个代码可能会很方便,因此您可以轻松地在两者之间进行切换。如果您可能必须回切或添加外部配置选项,则基于常量的if将为那些提供合理的升级路径。因此,就像许多事情一样,如果要解决特定的问题,那就去做。如果没有,请避免。

我认为人们做得太多的原因是:从怀疑(通常是正确的)到人们在遇到问题时实际上会阅读源代码控制历史;从害怕新的代码将无法正常工作,并希望一个简单的还原选项。要使您俩都满意,可以选择在“日期(日期)上更改为计算...。如果有任何问题,请参见源代码管理中的旧版本”或类似内容。


3

不,它没有用。该else块没有任何目的。如果不确定使用哪种实现,请将其注释掉,制作单独的类或将其保存在其他位置。而且,大多数情况下,您具有-或至少应该具有-源文件的本地或远程历史记录。


1
如果不是真的也没有太大的目的!if(true)实际上是无操作
Zachary K

当然可以,这是正确的。
阿尔卑斯

3

如果条件取决于编译时间常数,则应由编译器删除无效代码,因此从技术上讲,将其保留就不会有任何伤害。但是,我宁愿对其进行注释,因为这样可以提高代码的可读性。

如果您希望能够在两种代码替代品之间快速切换,则可以使用以下便捷的注释构造:

//*
alternative 1 is active
/*/
alternative 2 is commented out
//*/

如果仅删除/第一条注释行中的第一条,则它将变为:

/*
alternative 1 is commented out
/*/
alternative 2 is active
//*/

这样,您只需/在代码中添加或删除一个即可在备选方案之间切换。

乍一看可能有点奇怪,但是一旦习惯了它,就可以轻松地将其识别为某种模式。

您甚至可以链接它,从而使用单个字符一次切换多个块:

//*
first block of code for alternative 1
/*/
first block of code for alternative 2
/*/
second block of code for alternative 1
/*/
second block of code for alternative 2
//*/

我不会以这种方式使用它,但是它可以工作。


我不得不用笔和纸来研究它的工作原理。写作时非常不错的技巧,我会用,但是确定后肯定会删除。
罗曼·格拉

当问题仍然在stackoverflow上时,它看起来更明显,但确实正确突出了注释。
x4u 2011年

1

在某些罕见的情况下,旧代码及其已被替换的事实实际上应该保留在源代码中,以便将来的程序员被警告某些违反直觉的事情。在这种情况下,还需要某种注释,以解释为什么它仍然存在以及发生了什么。

与往常一样,编写易于维护的程序是要使事情变得更清晰,而不仅仅是遵循严格的规则。如果将无效代码保留下来,则更容易理解发生了什么,则将其保留下来。否则,将其取出。


这就是自述文件的用途
Wipqozn

0

编译器将忽略它。但是,我同意您的意见,只会删除else语句。假设您使用的是版本控制,您仍然可以通过查看文件的历史记录来查看旧代码。


0

这可能是个人观点,但是我发现在维护一段代码时,无效代码会分散注意力。对于任何给定的任务,您总是有不止一种方法来完成它,因此您必须选择一种。做研究,评估算法,然后选择一种。此后,代码不需要在其中包含任何其他方法。

如果有两个非常有力的竞争者,请写下有关替代方案的小注释,然后将其粘贴在项目Wiki或其他包含项目文档的地方。如果需要,您可以在一行注释中引用此文档,并概述为什么要阅读该文档。


0

我无法立即想到写死代码有用的情况。如果有其他算法,则:

  • 要么您保留了最有用的一个,而又消除了另一个,
  • 或算法适用于不同的情况,然后同时使用这两个条件,并在使用第一个算法时有条件地标识情况。

无论哪种情况,您最终都不会得到无效代码。


0

如果您不删除或注释死代码,则必须对其进行维护,以避免编译器错误。这是浪费时间。如果您有SCM,则将其删除。


SCM与SVN是否相同?如果否,那么我们没有SCM。我们有SVN。
哈里·乔伊,

1
SCM表示源代码管理(en.wikipedia.org/wiki/Source_Code_Management)。如果您有SVN,那么您就有SCM!;)

SCM实际上是指软件配置管理。如果您拥有SVN,则意味着您具有版本控制权,是否拥有SCM是另一个问题。
softveda 2011年

3
@Pratik:不,SCM实际上是软件链锯大屠杀。不这样认为是愚蠢的。没有像源代码管理,软件配置管理或供应链管理这样的傻瓜。SCM的真正含义是软件电锯杀人事件。
Lie Ryan

软件锯子还是软件大屠杀?
Roman Grazhdan

0

没有

一些程序员使用此样式作为注释的替代方法,并发现它很雅致。

if (1 == 0) 
{
    std::cout <<"I am a dead code capable of resurrection, once a programmer changes the condition!";
}

0

简单的答案是简单的否。死代码会引起混乱,并且可能会出现错误。在代码中键入字符后,就存在风险。因此,不要添加多余的东西。

一次我不得不写类似的东西是为了解决编译器错误,甚至编译器供应商建议使用这种解决方法。


0

您是否测试编写的无效代码?做任何事情来确认它可能很好吗?如果没有,请摆脱它。

对于将来的代码更改,您是否要验证无效代码仍然有效?如果没有,请摆脱它。

您不希望程序中有错误的代码,即使不使用它也是如此。在那里提示可以使用它。如果您不同时使用两个版本的代码,则通常不希望维护它们,因为这是多余的工作,而且由于感觉毫无意义,大多数人不会对无效代码进行出色的处理。

可能有理由保留注释掉的代码(或者在C或C ++中,使用#ifdef注释掉的代码),但这应附有注释,说明为什么它仍然存在以及它的作用是什么。


0

请注意,在Java中,由于代码无法访问,以下代码甚至无法编译:

int someFunc() {
    return 10;
    int x = 12;
    return x;
}

理想情况下,如果您的代码有问题,您希望尽早找到它,而不是让它投入生产并被用户发现。

如果编译器可以找到一类错误,请让编译器找到它。恕我直言,有人通过按照您所描述的方式编写无效代码来做的事情,正在试图规避该编译器错误,从而使任何可能引起的问题在运行时浮出水面。

您可能会争辩说无法到达无效代码,因此不会引起问题,但是在注释,支撑和缩进方面可能会有些许错误,从而可能导致这种情况发生。


同样在C#中它将编译,但将显示警告。
Morgan Herlocker 2011年

0

人们之所以会注释一些旧的逻辑,是因为他们害怕对代码进行大的更改。确实,一周后意识到旧代码实际上是正确的,现在您必须从头开始编写它实在是太难了。但这就是源代码控制的目的。如果您决定更改某些逻辑,请不要害怕丢失一些可以正常工作的当前代码。删除它,让您的SVN / Git / TFS为您处理版本控制。

如果不是这种情况,并且由于不关心YAGNI或DRY而只是产生了两种不同的逻辑来做某事,那么只需确保将其放置在人们可以使用的地方即可。如果您愿意的话,也许在那儿扔一个战略模式。只是不要做这些“如果...否则”的事情,这是不好的设计,并且很难维护。如果您确实认为某些代码有权存在,请确保可以使用它。


0

另一种看法是,基本上大多数专业程序员都认为代码的大小是敌人。看看这些博客文章:最好的代码根本不是代码,而Jeff Atwood是代码的最大敌人,Steve Yegge的,您可以找到更多的东西。

人们通常会通过牺牲性能(无关紧要)来做很多事情,以保持代码简洁,并防止代码库变得太大。因此,您真的认为100行无效代码可以是一件好事吗?


0

只有在您希望快速禁用某些内容并进行测试/回填的情况下,我才认为这很有用(说程序执行步骤A,B,C-都需要很长时间。回填期间,您可以选择禁用B和C如果您知道没有必要,请暂时将其加快)。
但事实是,在所有情况下,这都是很棘手的。而且,如果您确实看到回填代码已长期使用,则应以这样的方式编写代码:使用config来选择选项,而不是使用此类技巧。
我的快速经验法则是永远不要签入这种代码。如果您需要签入/版本控制,则意味着您将很快能够回到此状态,并且鉴于需求的变化,这始终是一件坏事。


0

实际上,拥有“死”代码的一种有用的方法是:当您希望您的程序引发一个巨大的异常时,因为它到达了某些本不应该发生的事件。这可能是编译器错误,或者是某人在线更改了您正在使用的测试中的逻辑并将其弄乱了。无论哪种方式,您的“其他”都会发出烟花。在这种情况下,您需要将其释放。

至关重要的是,错误消息中必须声明类似“紧急情况:我们永远不会在文件%s中的%d行中出现” ...

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.