2012-06-18 61 views
7

我在看朋友寄給我的一些代碼,他說:「它編譯,但不工作」。我看到他用的功能,而括號,是這樣的:爲什麼C++編譯器在使用沒有括號的函數時抱怨?

void foo(){ 
    cout<< "Hello world\n"; 
} 

int main(){ 
    foo; //function without parentheses 
    return 0; 
} 

首先我說的是「使用括號,你必須」。然後我測試了代碼 - 它確實編譯了,但是執行時不起作用(沒有顯示「Hello world」)。

那麼,它爲什麼編譯(編譯器沒有任何警告GCC 4.7),但不起作用?

+0

它確實工作。 'foo'被視爲一個函數指針。 'foo;'這一行只是一行無效的行。如果您最大限度地發出警告,您應該無條件地收到關於聲明的警告。 – RedX

+0

我看* *警告:語句是一個引用,而不是調用'foo'「*和*」警告:語句無效「*。您可能希望使用-Wall -Wextra – Flexo

+3

進行編譯(對於將來的問題,爲了使您的示例完整,值得放入#include 和任何名稱空間內容) – Flexo

回答

12

如果將警告級別設置得足夠高,它肯定會發出警告。

函數名稱評估爲函數的地址,是一個合法表達式。通常它被保存在一個函數指針中,

void (*fptr)() = foo; 

但這不是必需的。

11

您需要提高您使用的警告級別。 foo;是一個有效的表達語句(函數的名稱轉換爲指向函數的指針),但它沒有效果。

我通常使用-std=c++98 -Wall -Wextra -pedantic這給:

<stdin>: In function 'void foo()': 
<stdin>:2: error: 'cout' was not declared in this scope 
<stdin>: In function 'int main()': 
<stdin>:6: warning: statement is a reference, not call, to function 'foo' 
<stdin>:6: warning: statement has no effect 
3
foo; 

你 '使用' 的功能在這裏是不實際。你只是使用它的地址。在這種情況下,你正在使用它,但沒有真正使用它。

當您想將該函數作爲回調函數傳遞給某個其他函數時,函數的地址(即它們的名稱,不帶括號)很有用。

相關問題