2012-06-18 2 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'" * и * "warning: statement does not effect" *. Вероятно, вы хотите скомпилировать с -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; 

Вы на самом деле не 'с помощью' функции здесь. Вы просто используете его адрес. В этом случае вы принимаете это, но не используете его.

Адреса функций (то есть их имена без каких-либо скобок) полезны, если вы хотите передать эту функцию в качестве обратного вызова какой-либо другой функции.