2013-10-13 2 views
-1

Я пытаюсь написать:Typedef и объявление функции

typedef int foo(); 
... 
foo bar 
{ 
    return 1; 
} 

Но у меня есть error C2206, что ЬурейеЕ не может использовать для объявления функции. Что вызывает эту ошибку? Я думаю, foo bar должен компилироваться только как int bar().

+1

Типы функций не являются объектами. Вы не можете «объявить переменную типа функции». Вы можете только «объявить функцию». Вот как это язык. –

ответ

2

Эта декларация:

typedef int foo(); 

вполне допустимо. Он определяет foo как псевдоним для типа int(), или «функция возвращает int и не принимает никаких аргументов».

(В сторону: C использует (void) не указывают на отсутствие аргументов, C++ использует () Более ранняя версия этого ответа было основано на правилах C.).

Это чаще для определения определений типов для типов указатель на функцию а не для типов функций, но оба действительны. Учитывая вышеизложенное ЬурейеЕ, вы можете объявить функцию указатель на объект как:

foo *funcptr; 

Но вы не можете объявить или определить функцию с помощью ЬурейеЕ. Если язык допускает это, вы могли бы объявить функцию:

foo func; /* would be equivalent to "int func(void);" *if* it were legal */ 

или:

foo func { return 42; }; /* would be equivalent to 
          "int func(void) { return 42; }" 
          *if* it were legal */ 

Есть еще раз, когда это будет удобно. Стандартная signal функция, определенная в <signal.h> или <csignal>, имеет довольно сложную декларацию:

void (*signal(int sig, void (*func)(int)))(int); 

Вы можете определить typedef для типа функции обработчика сигнала:

typedef void (signal_handler)(int); 

бы позволила бы signal к быть объявлен как:

void (*signal(int sig, signal_handler *func); 

, но вы не можете себе это определение типа, чтобы объявить или определить свой собственный обработчик сигнала - хотя вы можете с пользой использовать его, чтобы объявить указатели сигнализировать функции обработчика:

signal_handler *funcptr = my_handler; 
signal(SIGINT, funcptr); 

То же самое относится и к аргументам указателя функции, требуемые qsort() и bsearch().

Так что, учитывая, что вы можете определить typedef для типа функции, почему вы не можете использовать его для объявления или определения функции?

Я не думаю, что есть какая-то серьезная причина. Язык просто не позволяет этого. Для объявления функций, одна проблема заключается в том, что

signal_handler foo; 

выглядит точно так же, как в объявлении объекта, но вместо этого объявить функцию (которая должна быть определена в другом месте). И разрешение определений типов для функции определения:

signal_handler foo { /* ... */ } 

потребует изменения грамматики языка - и было бы трудно увидеть параметры и возвращаемые типы при взгляде на определение. Кроме того, определения функций, в отличие от объявлений, требуют имен для любых параметров, что добавит еще один уровень сложности.

Но я считаю, что настоящая причина в том, что Деннис Ритчи, когда он проектировал С, либо не думал об этом, либо не думал, что это стоит (и у Страуструпа не было достаточной причины для измените это, когда он разработал C++).

+0

@GManNickG: Отличная точка; Я исправлю свой ответ. –

+0

Выглядит хорошо. :) – GManNickG

1

Заявления для указателя на функцию ЬурейеГо являются

typedef int (*foo)(); 

Также вы пропали без вести круглые скобки в вашем объявлении функции

foo bar() 
{ 
    return 1; 
} 

Также 1 не является допустимым значением указателя функции.

foo bar() 
{ 
    return 1; // this line is an error 
} 
+0

Извините, это опечатка. Исправленный. –

+0

@ St.Antario Я не вижу коррекции. – john

+0

@john Я думаю, что OP хочет 'bar' быть типа' foo', а не * return * type 'foo'. –

Смежные вопросы