2

我正在尝试使用 scala 编译器 Y 警告,但我认为我做得不对。在下面的示例中,未使用 nums ,因此我希望 -Ywarn-value-discard 对此打印警告。有两个 if 条件,一个嵌套在另一个内部。孩子 if 的条件与父母的完全相反,因此其中的任何内容都是死代码。但是 -Ywarn-dead-code 并没有对此发出警告。谁能建议我可能做错了什么?任何指针将不胜感激。

object DeadCodeWarn{
  def main( args: Array[ String ] ) {
    val nums = 1 to 100
    //There should be a warning for squares
    //as its a non-unit expression thats not
    //used in any computation. Y-warn-value-discard
    val squares = nums.map( x => x * x ) 

    if( nums.length == 100 ){
      println( "should be printed" )
      if( nums.length !=100 )
      {
        //-Ywarn-dead-code
        println( "Dead code, so should be warned against" )
      }
    }
  }
}

$scalac -Xlint -Ywarn-all DeadCodeWarn.scala默默地成功。

4

2 回答 2

4

-Ywarn-value-discard

该值不会被丢弃,它被分配给val! 问题val是未使用

带代码:

package foo

case class Foo(x: Int) {
  def foo: Int = {
    val y = 2;
    x
  }
}

我得到了 scalac 2.11.5 和-Ywarn-unused

[warn] /.../foo.scala:5: local val in method foo is never used
[warn]     val y = 2;

-Ywarn-dead-code

编写常见逻辑不起作用的反例很容易:

// Evil mutable class
class Arrayish {
  private var x: Int = 100
  def length(): Int = {
    val res = x
    x += 1
    res
  }
}

def test(nums: Arrayish): Unit =
  if (nums.length == 100) {
    println( "should be printed" )
    if (nums.length != 100) {
      println("Dead code, so should be warned against")
    }
  }

运行死代码:

scala> test(new Arrayish())
should be printed
Dead code, so should be warned against

或者

class NonEqual {
  def ==(x: Int): Boolean = true
  def !=(x: Int): Boolean = true
}

class NaNLength {
  val length: NonEqual = new NonEqual
}

def test2(nums: NaNLength): Unit =
  if (nums.length == 100) {
    println("should be printed")
    if (nums.length != 100) {
      println("Dead code, so should be warned against")
    }
  }

死代码也运行:

scala> test2(new NaNLength)
should be printed
Dead code, so should be warned against

Scalac 编译器不够聪明,无法区分表现良好和表现不佳的情况。


如果您要提交错误/功能请求,请提及以下示例:

def test3(nums: Array[Int]): Unit = {
  if (true) {
    println("should be printed")
    if (false) {
      println("Dead code, so should be warned against")
    }
  }
}

def test4(nums: Array[Int]): Unit = {
  val hundred = nums.length == 100
  if (hundred) {
    println("should be printed")
    if (!hundred) {
      println("Dead code, so should be warned against")
    }
  }
}

似乎 scalac 死代码报告器不像 Java 那样优美。我希望 scalac 确实优化了这些示例,但它不应该太复杂。

于 2015-02-11T05:29:42.797 回答
1

在玩弄了一些代码之后,看来这根本不是捕获死代码的情况。我将继续阅读编译器代码本身,但经过审查,似乎已经消除了死代码。消除后是它似乎发出警告的时候。所以,如果你回顾一些简单的东西

def foo = {return 1; 1}

您会看到最终代码只是简单地返回 1,甚至没有发出第二个 1。但是,如果您看一下这个嵌套的最终代码,if您会发现第二个if没有被消除。

继续提交一个错误,虽然我不确定这会有什么样的优先级。

于 2015-02-11T04:41:53.010 回答