Чтение сложных объявлений типов в C/C++ задача непростая. Нет, все когда-то слышали, что надо идти кажется направо, а потом вроде налево и тем еще что-то про скобки было, но вот такое объявление может поставить в тупик:
int (*(*)())()
В статье Reading C type declarations приведено подробное описание и наглядные примеры расшифровки таких объявлений. Встречаются они редко, но всегда в самое неподходящее время...
20 коммент.:
ИМХО самое ужастное, что есть в C - это указатели на функции.
Да ничего ужасного в них нет. Просто с ними редко приходится работать и синтаксис у программиста вылетает из головы. Если руку набить, то работать с ними становится легко и приятно.
Тут определяется указатель на функцию, не принимающую аргументов и возвращающую указатель на функцию, которая возращает int и так же непринимает аргументов.
то есть эквивалентно такому коду
typedef int (*foo)();
typedef foo (*bar)();
Я не говорю, что это чрезмерно сложно. Просто это очень некрасиво. В во многих других языках это сделано гораздо красивее.
Э-м-м... А это не указатель на функцию, типы аргументов которой не определены?
Э-м-м... А это не указатель на функцию, типы аргументов которой не определены?
Не очень поняла, что значит "типы аргументов не определены". Там две функции, обе без аргументов.
Вообще Nunquam dormio написал правильный тип. По ссылке рассказывается как он получается.
Nunquam dormio пишет...
Да ничего ужасного в них нет. Просто с ними редко приходится работать и синтаксис у программиста вылетает из головы. Если руку набить, то работать с ними становится легко и приятно.
Собсвенно мне приходилось писать под платформу, на которой был только C компилятор(причём результат компиляции выполнялся на виртуальной машине). А хотелось с минимальными усилиями перенести туда кучу кода на C++. И для этой платформы я разрабатывал фрэймворк, использующий что-то вроде классов с наследовнием и виртуальными функциями. Вся система была достаточно сильно завязана на указатели на функции. Работать с ними было действительно легко, но почему-то хотелось лучшего.
void не вписан, для C это и будет, что аргументы и их кол-во не определено
Анонимусу: сенькс, именно это я и собирался написать.
Чтобы было понятнее:
$ cat > test.c << EOF
> void test(){}
> int main(){
> test(1);
> return 0;
> }
> EOF
$ gcc -o test.exe test.c
$ cat > test1.c << EOF
> void test(void){}
> int main(){
> test(1);
> return 0;
> }
> EOF
$ gcc -o test1.exe test1.c
test1.c: In function `main':
test1.c:3: error: too many arguments to function `test'
Скобки без аргументов или скобки с void означают, что у функции нет аргументов вообще, а не "количество неопределено".
Неопределенное количество аргументов это >= 0 (см. printf(const char*,...) у которого параметров может быть >=1).
Все подобные определения можно сделать более удобочитабельными путём последовательного создания нескольких typedef'ов. Но некоторым кажется, что лучше сэкономить пару строк кода, ведь все равно в данной конструкции они для себя разобрались.
Хм. сабж поста был Reading С (!)type declarations, т.е migmit и иже :) правы, а nixaroid... немножко невнимателен.
;) sse
...прям как я :-[ прошу прощения у niRaXoid'а
Анонимный(15/10/07 11:36), то есть, как я понял, отсутствие аргументов в скобках не эквивалентно (void) для С???
В статье кстати не затрагивали аргументы функции для того, чтобы не загромождать процесс разбора типа. Но абстрактное определение С
int (*(*foo)())()
будет отличатсья от
int (*(*foo)(int))().
А void f(void); эквивалентно void f();
Или я не прав?
Не прав. См. приведённый мною выше пример - void test() вызванный как test(1) компилится (и даже работает), а void test(void) - нет.
А какая версия gcc?
А что будет для такого кода?
void test(){}
int main(){
test(1,'a');
return 0;
}
Интересно как можно получить доступ к аргументу такой функции как void test();? Через va_list?
3.4.4, cygwin
Компилится, запускается.
Да, через va_list, видимо.
Отправить комментарий