当前位置: 首页 > 知识库问答 >
问题:

我的编译器会忽略无用的代码吗?

冷英博
2023-03-14

我通过网络回答了一些关于这个主题的问题,但我没有找到任何答案,或者是另一种语言的问题,或者它没有完全回答(死代码不是无用代码),所以我的问题是:

编译器是否忽略了(显式或非显式)无用的代码?

例如,在此代码中:

double[] TestRunTime = SomeFunctionThatReturnDoubles;
// A bit of code skipped
int i = 0;
for (int j = 0; j < TestRunTime.Length; j++)
{

}
double prevSpec_OilCons = 0;

for 循环会被删除吗?

我使用.net4.5和vs2013

背景是我维护了很多代码(我没有写),我想知道无用的代码是否应该成为目标,或者我是否可以让编译器来处理这个问题。

共有3个答案

梅耘豪
2023-03-14

循环中,每次迭代中都隐含了两个操作。增量:

j++;

和比较

j<TestRunTime.Length;

因此,循环不是空的,尽管它看起来是空的。最后会执行一些东西,当然编译器不会忽略。

在其他循环中也会发生这种情况。

苏涛
2023-03-14

无法删除循环,代码没有死,例如:

  // Just some function, right?
  private static Double[] SomeFunctionThatReturnDoubles() {
    return null;
  }

  ...
  double[] TestRunTime = SomeFunctionThatReturnDoubles();
  ...
  // You'll end up with exception since TestRunTime is null
  for (int j = 0; j < TestRunTime.Length; j++)
  {
  }
  ...

通常,编译器无法预测SomeFunctionThatReturnDoubles的所有可能结果,这就是为什么它保留循环的原因。

姬存
2023-03-14

好吧,您的变量iprevSpec_OilCons,如果没有在任何地方使用,将被优化掉,但不是您的循环。

因此,如果您的代码看起来像:

static void Main(string[] args)
{
    int[] TestRunTime = { 1, 2, 3 };
    int i = 0;
    for (int j = 0; j < TestRunTime.Length; j++)
    {

    }
    double prevSpec_OilCons = 0;
    Console.WriteLine("Code end");
}

在ILSpy下,它将是:

private static void Main(string[] args)
{
    int[] TestRunTime = new int[]
    {
        1,
        2,
        3
    };
    for (int i = 0; i < TestRunTime.Length; i++)
    {
    }
    Console.WriteLine("Code end");
}

由于循环有几个语句,如比较和增量,因此可用于实现较短的延迟/等待时间。(尽管这样做不是一个好的做法)。

考虑以下循环,这是一个空循环,但执行需要大量时间。

for (long j = 0; j < long.MaxValue; j++)
{

}

你代码中的循环,不是死代码,就死代码而言,下面是死代码,会被优化掉。

if (false)
{
    Console.Write("Shouldn't be here");
}

循环甚至不会被 .NET 抖动删除。基于这个答案

 类似资料:
  • 忽略编译器警告 格式 #pragma clang push #pragma clang diagnostic ignored "错误类型" // 存在警告的代码 #pragma clang pop > 1.在需要忽略的警告处右键 -- Reveal in Log 2.会给出警告的详细信息,其中包括警告的类型 3.高亮选中的便是这个警告的类型 4.在警告代码处增加如下代码 Command

  • 问题内容: 我编译的Go代码并未在Linux上以扩展名结尾。 有关在.gitignore文件中忽略这些提示的任何提示? 问题答案: 将您的构建产品与源代码分开。这有几个优点: 您可以同时启动同一代码的许多不同版本,而无需创建多个克隆 可以很容易确定自己确实做了一次清洁工作;将删除越野车将丢失的文件 您可以从源代码树的只读副本(例如CD-ROM)开始构建 您不太可能意外提交生成的文件 将清除您的源代

  • 如果我保存相同的代码,编译器会再次编译程序还是会留下旧的编译代码。如果它不会再次编译,意味着它如何识别它是相同的代码。

  • 关于目标旗。与使用Java6编译器编译代码相比,使用针对Java6的Java8编译器编译Java6代码(当代码仍然在JVM6上运行时)有什么好处吗?

  • 我有一个编译器错误问题,请查看以下代码: 问题在于编译器忽略了 foo 函数上的“const”,使得对 foo 的调用非法(const int* to int*)。 严重程度代码描述项目文件行抑制状态错误C2664'ululfoo(const::类型)':无法将参数1从'const int*'转换为'const Mystrt::类型' 我在Visual Studio和gcc的5.3编译器中测试了以

  • 想改进这个问题吗?通过编辑这篇文章添加细节并澄清问题。 如果我保存相同的代码,编译器会再次编译程序,还是会保留旧的编译代码。如果它不再编译,意味着它如何识别它是同一个代码。