条件操作员警告

时间:2014-11-09 05:00:38

标签: swift conditional-operator

我收到will never be executed警告,其中包含以下代码

代码:

func f1()
{
    var a1 : Int = 100

    a1 = 1

    var a2 = (a1 > 40 ? 1 : 0) //No warning

    var a3 = (a1 > 40 ? "aaa" : "bbb") //Warning - will never be executed (points to "aaa")
}

问题:

  • 我知道基于上述逻辑,a3会获得值"bbb"但是应该有 警告?
  • 为什么没有警告评估a2
  • 的值
  • 编译器如何实际评估这个?我认为这些值将在运行时确定。 (注意分配后a1的值会发生变化)

1 个答案:

答案 0 :(得分:2)

var a3 = (a1 > 40 ? "aaa" : "bbb") //Warning

行上有警告的原因,因为它实际上调用了一些代码。它通过调用String的init()来构造一个String实例。

a1 > 40 ? 1 : 0

这没有任何警告,因为它是原始值,不涉及任何init()或实例创建等。

事情变得有趣..

    func f1()
    {
        struct F {
            init(x: Int){
            }
        }

        var a1 : Int = 100

        a1 = 1

        var a2 = (a1 > 40 ? Int(1) : Int(0))      // No Warning

        var a4 = (a1 > 40 ? Int(Int(1) + UInt8(2)) : Int(0)) // Warning

        var a3 = (a1 > 40 ? String("aaa") : "bbb")  // Warning

        var a5: F = (a1 > 40 ? F(x: a2) : F(x: a1))  // Warning
    }

为什么a3和a5会收到警告,可以解释一下。但是为什么a2没有警告,它调用Int(1),它应该调用struct Int的init()。原因是“编译器优化”。 a4有警告,表明swift编译器的优化相对较浅。 :)

修改

从生成的代码中,您可以看到差异。对于简单的Int(0),不调用struct的init。

   var a = Int(0)

   0x1006946d0:  pushq  %rbp
   0x1006946d1:  movq   %rsp, %rbp
   0x1006946d4:  subq   $0x20, %rsp
   0x1006946d8:  movq   %rdi, -0x10(%rbp)
   0x1006946dc:  movq   %rdi, -0x18(%rbp)
-> 0x1006946e0:  movq   $0x0, -0x8(%rbp)
   0x1006946e8:  callq  0x1006b0f14               ; symbol stub for: objc_release
   0x1006946ed:  addq   $0x20, %rsp
   0x1006946f1:  popq   %rbp
   0x1006946f2:  retq   

   var a2 = Int(Int(0x0) + UInt8(0xE))

   0x1007175f0:  addq   $0x8, %rax
   0x1007175f6:  movq   0x1ebc3(%rip), %r8        ; (void *)0x0000000104a89d88: protocol witness table for Swift.UInt8 : Swift.Strideable
   0x1007175fd:  movq   0x1eaac(%rip), %rcx       ; (void *)0x0000000104a92f80: direct type metadata for Swift.Int
   0x100717604:  addq   $0x8, %rcx
   0x10071760b:  movq   0x1eb5e(%rip), %rdx       ; (void *)0x0000000104a8b228: protocol witness table for Swift.Int : Swift.SignedNumberType
   0x100717612:  movq   0x1eb67(%rip), %rsi       ; (void *)0x0000000104a8b0c8: protocol witness table for Swift.Int : Swift._BuiltinIntegerLiteralConvertible
   0x100717619:  leaq   -0x38(%rbp), %r9
   0x10071761d:  leaq   -0x30(%rbp), %r10
   0x100717621:  leaq   -0x28(%rbp), %r11
   0x100717625:  movq   %rdi, -0x18(%rbp)
   0x100717629:  movq   %rdi, -0x20(%rbp)
-> 0x10071762d:  movq   $0xb, -0x28(%rbp)
   0x100717635:  movb   $0xe, -0x30(%rbp)
   0x100717639:  movq   %rdi, -0x40(%rbp)
   0x10071763d:  movq   %r9, %rdi
   0x100717640:  movq   %rsi, -0x48(%rbp)
   0x100717644:  movq   %r11, %rsi
   0x100717647:  movq   %rdx, -0x50(%rbp)