无法访问的代码:错误或警告?

时间:2010-02-17 13:04:09

标签: compiler-construction language-agnostic language-design

这是一个语言设计问题:

您认为无法访问的代码(通常在编程语言中)应该引发警告(即“报告问题并反正编译”)或错误< / strong>(“拒绝编译”)?

就个人而言,我强烈认为这应该是一个错误:如果程序员编写了一段代码,那么它应该始终是为了在某些场景中实际运行它。但是,例如C#编译器似乎不同意这一点,只是报告了一个警告。

注意:我意识到良好的死代码检测是一个非常棘手的问题,但这不是这个问题的焦点。

以下是一些代码片段的示例,其中一些语句显然无法访问:

return;
foo();

-

throw new Exception();
foo();

-

if (...) {
  return;
} else {
  throw new Exception();
}
foo();

12 个答案:

答案 0 :(得分:28)

错误表示编译器在物理上无法处理您的代码。

警告意味着编译器能够处理您的代码,但它相信您所写的内容在某种程度上是错误的。

我觉得很明显 - 这应该是一个警告。

此外,我决定缩短调试方法的情况如下:

public bool ShowMenu()
{
    return true;
    /* The standard implementation goes here */
}

我知道它的错误,但是对于编译器要求我也注释掉代码只是一种痛苦。

答案 1 :(得分:25)

在调试时故意创建死代码是很常见的 - 防止这种情况的编译器不太可能受其用户欢迎。

答案 2 :(得分:12)

一般来说,这应该是一个错误。

然而,我想到了一个例外:

if (false) {
  doStuffThatITemporarilyDisabled();
}

如果您的编译器拒绝编译类似的代码,一些开发人员可能会抱怨。

答案 3 :(得分:8)

我认为警告是恰当的。然后,用户可以决定使用您的OTHER开关,将“将所有警告视为错误”用于执行发布版本。赋予开发人员权力总是比将强制性随机选择强加给他更好。

答案 4 :(得分:8)

我认为这应该是一个警告。

一般来说,通常的规则是'你应该将警告视为错误'。如果我无意中编写了无法访问的代码,我会在警告中看到它并进行修复。

然而,有时候,就像Neil所说,你故意创建死代码,用于调试目的或任何原因。如果编译器不允许我这样做,我真的非常讨厌它。

答案 5 :(得分:4)

如果您的语言具体说明:

  • 将死代码视为错误
  • 不支持C风格的“文本级”预处理
  • 缺少可以使用直线式注释嵌套的块样式注释

......那真的很糟糕。必须能够禁用大块代码而不必将其从文件中删除。

答案 6 :(得分:3)

我更喜欢(可证明)无法访问的代码产生警告或通知(如警告,只有没有负面含义)。主要是因为这使得自动代码生成更容易。

答案 7 :(得分:2)

在开发阶段使用该代码的一个很好的理由是:您希望暂时禁用某些代码,但您仍然希望在语法上检查此代码。

例如:

int i = 2, j = 3;
int result = 0;

// FIXME: Commented out for now because I have to recheck calculation
if (false) {
  result = i*2+j+3+i*j;
}

System.out.println("Result of difficult calculation = "+result);

如果你把列表“result = i * 2 + j + 3 + i j;”只需在 / 评论* / 中,您就可以确定在删除或重命名某些变量(例如i)时,您不会收到错误消息。

答案 8 :(得分:2)

默认情况下,它应该是一个警告,带有编译器标志,允许将其视为错误。 要求一个或另一个是不可改变的。

答案 9 :(得分:2)

我认为这应该是一个警告,因为与Roalt说的原因相同。一个好的编译器也应该排除这个代码被编译。

答案 10 :(得分:2)

我还不清楚为什么Java将死代码实现为错误。我使用C和Objective-C,它们有预处理器,因此我可以轻松地使用预处理器指令来启用(或屏蔽)一个函数/方法,如:

// C code
#define ENABLE_FOO //Comment off this to turn off foo(void);
int foo(void)
{
#ifdef ENABLE_FOO
    // Do actual stuff.
    int returnVaue = 2;
    // ...
    return returnValue;
#else
    return 0; // Turned off
#endif
}
// Compiling using clang, enforcing dead code detection:
// clang main.c -Wall -Werror

或者像Objective-C一样,提供反射:

// Class
#define MYCLASS_ENABLE_FOO // Comment off to enable -[MyClass foo]
@interface MyClass : NSObject
#ifdef MYCLASS_ENABLE_FOO
- (int)foo;
#endif
@end
// The like is done in implementation.
// Invoking:
int main(int argc, char **argv)
{
    MyClass *object = [[MyClass alloc] init];
    int value = ([object respondsToSelector:@selector(foo)]) ? // Introspection.
                [object foo] : 0;
    printf("Value: %d", value);
    return 0;
}

答案 11 :(得分:2)

答案是关于无法访问的代码是否触发错误或警告的最终决定应留在开发人员手中。编译器应该允许。

在生产发布代码的情况下,余额有利于它是一个错误。任何生产程序都不应包含无法访问的代码。

在调试/测试代码的情况下,余额有利于它是一个警告。能够禁用部分代码进行调试或测试非常方便。

以上仅涉及手工编写的代码。对于由自动化工具生成的代码,天平有利于将其作为警告或忽略。包含无法到达部分的代码生成没有特别的不良后果,可能极难避免。