2017-03-01 29 views
4

我想知道是否有方法讓編譯器明白兩個if語句不能同時爲真,並添加一個「隱含的else」。例如該代碼示例中:隱式else編譯器優化

int main() { 
    char c; 
    scanf_s("%c", &c, 1); 
    if (c == '1') { 
     printf("received 1\n"); 
    } 

    if (c == '2') { 
     printf("received 2\n"); 
    } 

    return 0; 
} 

c不能'1''2',但在Visual Studio編譯和拆卸我注意到,它會檢查第二if,不管是什麼之後。

+1

檢查版本構建。 –

+2

你期待什麼答案,除了*「這是可能的,但取決於編譯器」*? – user694733

+0

@BaummitAugen我檢查了發佈版本。 – yeger

回答

0

我會在LLVM/CLANG的背景下回答,因爲我對它的內部知識並不熟悉。

如果你確實打開了opt中的mem2reg優化,它會將c視爲臨時而不是變量(在寄存器分配之前的階段)。

在那裏優化器可以做出所需的假設,在這種情況下,如果第二個是在第一個內部,那麼它將被DCE刪除。

但我想不出LLVM套件會添加「elseif」的任何傳遞。

對於像gcc/msvc這樣的其他編譯器也不能這麼說。

0

難道一個編譯器理論上執行你建議的優化?是的,它絕對可以,但要確保在編譯器中檢測這種場景所需的語義分析是無缺陷的,這絕對是不平凡的,問題是開發工作是否無法在其他地方變得更好。

1

我想知道是否有方法讓編譯器明白兩個if語句不能同時爲真,並添加一個「隱含的else」。

是的,有:英特爾C編譯器icc 17呢,這可被證實與Matt Godbolt's Compiler Explorer,但既不鐺也不GCC似乎執行該優化。

0

由於scanf_s()被賦予一個指向變量c的指針,所以這個變量不能再被認爲是局部變量。先驗地說,該函數可以將該指針存儲在某處,並且任何其他函數(編譯器未知的)都可以通過該指針存儲某些內容,例如對printf("received 1\n")的調用。

換句話說,編譯器不能做這種優化,除非它知道函數scanf_s()printf()在做什麼。