Приведите long к указателю на функцию? - PullRequest
4 голосов
/ 04 марта 2012

У меня есть следующий код:

long fp = ...
void (*ptr)(long, char*, char*) = fp;

long fp - это правильный указатель на функцию, который указывается как long. Я получаю стандартное предупреждение «делает указатель из int без приведения». Я хочу быть в состоянии скомпилировать с:

-std=iso9899:1990 -pedantic-errors

, который превращает это предупреждение в ошибку. Вопрос в том, что является правильным составом актеров. Я пробовал разные догадки, например ::100100

void (*ptr)(long, char*, char*) = (void)(*)(long, char*, char*) fp;

Но, похоже, не могу найти правильного.

Ответы [ 4 ]

7 голосов
/ 04 марта 2012

Вероятно, это что-то вроде:

void (* ptr)(long, char, char *) = (void (*)(long, char, char *))fp;

но я предлагаю использовать typedef и забыть обо всем этом беспорядке:

typedef void (* fnPtr)(long, char, char*);
fnPtr ptr = (fnPtr) fp;
7 голосов
/ 04 марта 2012

«Правильное» приведение приведено ниже:

void (*ptr)(long, char*, char*) = (void (*)(long, char*, char*))fp;

Очевидно, это можно привести в соответствие с подходящим определением типа.

Но в любом случае результат этого определяется реализацией.Если можете, избегайте этого и поддерживайте указатель в типе указателя.Следующим лучшим вариантом будет использование intptr_t, если оно доступно.

4 голосов
/ 04 марта 2012

Единственный «правильный» способ - вообще не приводить к типу, а копировать двоичное представление:

2 голосов
/ 04 марта 2012

Основная проблема здесь в том, что ANSI-C не позволяет этого, несмотря на то, что бесчисленные C-API-интерфейсы полагаются на эту функцию.Поэтому вы, скорее всего, столкнетесь с проблемами при компиляции с -pedantic.Как указывалось другими авторами, вы можете обманывать актеров, используя такие вещи, как memcpy() или тип объединения для кастинга.

Кстати, POSIX гарантирует, что это будет работать, поэтому часть о «реализации-определенные результаты "становится намного менее страшным.

...