2009-09-29 5 views
3

, имеющее эту проблему на Mac с gcc 4.0.1 build 5370, XCode 2.5. Фрагмент кода:Ошибка: неверное преобразование из 'void (*) (...)' to 'void (*)()'

есть объявленная функция, второй параметр вызывает проблему:

void ffi_call(ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) 

назвав его так:

typedef void (*FuncPtr)(); 
FuncPtr func = some_function_pointer; 
ffi_call(null, func, ...); 

причиной ошибки на третьей строке. Похож, что 'void func (void)' отличается от 'void func()' для gcc 4.0.1

Любые идеи о любом gcc-переключателе или просто gcc-обновлении помогли бы? Спасибо за помощь Хонза Б.

ответ

3

Если вы программируете на C, void func() и void func(void) не то же самое. void func() эквивалентен void func(...). (Это отличается от C++).

Вы можете попробовать сделать что код компилируется в C++ (если это то, что вы на самом деле намереваясь), или, если не просто изменить FuncPtr ЬурейеЕ к typedef void (*FuncPtr)(void).

+0

Спасибо за ответ. К сожалению, код скомпилирован как C. Я не могу изменить FuncPtr. Должна быть возможность скорее изменить объявление функции. Но я считаю, что некоторые конфигурации или gcc-обновления (например, с помощью сборки 5484) помогут. – 2009-09-29 15:41:47

+0

'void func();' является прототипом для функции, принимающей неопределенное, но фиксированное количество аргументов; 'void func (...);' является прототипом для функции, принимающей переменное число аргументов. – pmg

+0

Но декларация отличается другим способом: недействительного (* PTR)() недействительных (* PTR) (аннулируется) которые IMHO как функции ш/о в параметре Я. В декларации нет .... – 2009-09-29 15:57:09

0

Существует два вида C, и им будет очень сложно смешивать их.


компиляторы должны иметь обратную совместимость, так как много кода было написано в начале C. Можно смешивать два стиля, но это может привести к путанице и даже во время выполнения ошибок, потому что правила соответствуют только для программ, которые являются полностью одним стилем или полностью другим.

В унаследованной C («K & RC») есть такие вещи, как: f(){/* stuff */} и

double f(d) 
double d; 
{ stuff } 

Переднее заявление в наследство стиль вполне может использовать (), даже если это действительно (d), потому что не было никакого способа, чтобы указать тип, поэтому мало смысла иметь формальный параметр.

И в соответствии с стилем C89- и C99 у вас есть знакомый double f(double); для декларации и double f(double d) { /* stuff */} для определения. double f(void) - это способ ANSI сделать это, но double f() по-прежнему является «законным», но неразумным сочетанием двух языковых уровней.

0

Да, void func(void) не соответствует void func().

Но любой указатель на функцию можно представить в void (*)func() и вернуться к исходному типу. Таким образом, вы можете изменить тип параметра указателя функции в своей функции C.

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

+0

Тип-литье - это то, что устраняет проблему. Спасибо за ответы. Нет необходимости в переносимости, поскольку код является платформенным пространственным (только для Mac). Я могу подтвердить, что более новая версия, затем gcc 4.0.1, обрабатывает эту скважину (или вообще неправильно). Не уверен, что он просто обращен к предупреждению или полностью игнорируется. – 2009-09-29 21:10:52