LINUX.ORG.RU

рекурсивный прототип

 ,


0

3

Хочется объявить прототип: указатель на функцию, которая возвращает аналогичную(с тем-же прототипом) функцию.

typedef void * (*foo)(); // <- вместо void *, должен быть foo

собственно как ?

★★★★★

Рекурсивными могут быть только структуры, так что ну ты понел (компилить с -std=c99):

#include <stdio.h>

struct cont;

typedef struct cont (*func)();

struct cont {
    func thunk;
};

struct cont bar();

struct cont foo()
{
    printf("123\n");
    return (struct cont){bar};
}

struct cont bar()
{
    printf("456\n");
    return (struct cont){foo};
}

int main()
{
    func thunk = foo;
    for (int i = 0; i < 10; i++) {
        thunk = (thunk()).thunk;
    }
}

ilammy ★★★
()
Ответ на: комментарий от ilammy

обходные пути мне известны, и обернуть функцию структурой не самый корректный из них.

вопрос остается открытым.

MKuznetsov ★★★★★
() автор топика
Ответ на: комментарий от MKuznetsov

Я не думаю, что это возможно сделать по-другому in type-safe way. Тайпдефы не вводят новые типы в отличие от структур.

ilammy ★★★
()

прототип: void *foo();

функция, возвращающая указатель на прототип: void (*func())();

anonymous
()

или

прототип:

bool foo(int);

ф-я, возвращающая указатель на прототип:

bool (*func(int))(int);

или

double foo(bool, int);

double (*foo(bool, int))(bool, int);

anonymous
()

Я так и не придумал как такое сделать, когда писал комбинатор на спп. Нужно со структрурами делать. Но я не доделал, т.к. не интересно стало.

nanoolinux ★★★★
()
Ответ на: комментарий от nanoolinux

придутся ограничится прототипом void *(*foo)() и только писать в документации что возвращать надо на самом деле ук-ль на функцию строго определённого вида. Компилер это дело жрёт, лишних приведений к типу не требует и ошибок не генерит; хотя в обшем смысле это и не корректно.

#include <stdio.h>
typedef void *(*foo)();

void *f1() {
	printf("Hello\n");
	return NULL;
}
void *f2() {
	return f1;
}

int main() {
	foo pf1;
	foo pf2;
	pf2=f2;
	pf1=pf2();
	pf1();
	return 0;
}
кстати интересно ругаются ли на такой код другие компиляторы? (просто нет под рукой, не могу проверить)

MKuznetsov ★★★★★
() автор топика
Ответ на: комментарий от MKuznetsov

кстати интересно ругаются ли на такой код другие компиляторы? (просто нет под рукой, не могу проверить)

gcc -pedantic ругается как положено.

ilammy ★★★
()
Ответ на: комментарий от MKuznetsov

Чем такой вариант не устраивает?

#include <stdio.h>
typedef void *(*foo)();
typedef void *(*(*pfoo)())();
void *f1() {
	printf("Hello\n");
	return NULL;
}
void *(*f2())() {
	return f1;
}
int main() {
	foo  pf1;
	pfoo pf2;
	pf2=f2;
	pf1=pf2();
	pf1();
	return 0;
}
alexku
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.