2012-12-14 46 views
4

在下面的代碼片段中,主函數調用沒有任何參數和圓括號的foo函數。奇怪的是,這個代碼可以由gcc編譯。我實際上檢查了彙編代碼,發現編譯器忽略了這一行。所以我的問題是在哪種情況下使用這種代碼?或者gcc的支持只是一個巧合,實際上它完全沒用。通過objdump的甩不帶參數和括號的調用函數

int foo(int a,int b) 
{ 
    return a+b; 
} 
int main() 
{ 
    foo;  // call foo without parameter and parenthesis 
    return 0; 
} 

它的彙編代碼-d

00000000004004c0 <main>: 
    4004c0: 55      push %rbp 
    4004c1: 48 89 e5    mov %rsp,%rbp 
    4004c4: b8 00 00 00 00   mov $0x0,%eax 
    4004c9: 5d      pop %rbp 
    4004ca: c3      retq 
    4004cb: 0f 1f 44 00 00   nopl 0x0(%rax,%rax,1) 
+0

沒有函數在沒有括號的情況下被調用。但是,[REBOL編程語言](https://en.wikipedia.org/wiki/REBOL)實際上允許您在沒有括號的情況下調用函數。 –

回答

1

foo是沒有得到調用,它只是指(並沒有分配到任何東西)。

6

評估表達式foo(給出函數的地址),並且結果被丟棄。如果沒有()運算符,則不調用該函數。

+1

'foo'甚至沒有評估。 'foo'只是源代碼中一個可讀的名字,它指向一個函數的地址。這個地址沒有被調用,所以還沒有任何「結果」丟棄 – Alexander

+0

@Alexander 123是一個C定義的表達式,foo也是如此。其實任何事物都是表達式,任何表達式都會被評估。 123評估爲整數123,123L評估爲長123,foo評估爲功能地址。我同意評估不會在運行時發生,我明白你的意思。但是,從理論上講,在編譯時,人類可讀的符號被評估並用其地址代替,然後被忽略(或者簡單地優化爲不存在)。所以答案是正確的。 – FrancescoMM

9

這是沒有比擁有任何其他類型的表達式,而忽略它的價值,就像不同:

int main(void) 
{ 
    42; 
    return 0; 
} 

沒有什麼特別的,這是調用該函數,因爲函數調用運營商()不正在使用。你所做的只是「計算」函數的地址,然後忽略它。

+0

那麼這樣做有什麼意義呢?我遇到了一段代碼,也做到這一點,不知道爲什麼。 –

+1

@JeffersonH​​udson我認爲沒有任何意義。任何理智的編譯器都會將其編譯爲無,即它將被忽略,因爲它沒有副作用。它可能是調試的遺留物,或者只是一個編輯錯誤。 – unwind