2014-11-09 139 views
1

我得到一個警告,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值分配後變更)
+0

我在操場上沒有收到任何警告。 – Shuo 2014-11-09 05:05:01

+0

我創建了一個OS X命令行工具項目,我得到了這個警告 – user1046037 2014-11-09 05:06:44

+0

我也沒有在命令行工具中得到警告。你使用的是什麼版本的Xcode,這是main.swift文件中唯一的代碼? – drewag 2014-11-09 05:09:16

回答

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) 
+0

Int和String都是Swift中的struct。嘗試下面的代碼:'var a2 =(a1> 40?Int(1):Int(0))//沒有警告'因此,都調用初始化/構造函數,但沒有警告爲Int,而出現警告字符串 – user1046037 2014-11-09 05:53:53

+0

a2和a3類似,但沒有a2的警告,並且a3有警告。兩者都使用構造函數/初始化程序。而a4有一個警告......使它更有趣(令人困惑) – user1046037 2014-11-09 05:59:36

+0

@ user1046037這是編譯器優化的地方。Swift編譯器試圖生成高性能代碼,因此它刪除了Int()的init。如果感興趣,您可以閱讀生成的程序集。 – Shuo 2014-11-09 06:03:47