views:

570

answers:

3

Hi, having this problem on Mac with gcc 4.0.1 build 5370, XCode 2.5. The code snippet is:

there is a declared function, the second parameter cause the problem:

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

calling it like this:

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

cause the error on the third line. Looks like 'void func(void)' is different from 'void func()' for gcc 4.0.1

Any ideas about any gcc switch or just gcc update would help? Thanks for help Honza B.

+2  A: 

If you are programming in C, void func() and void func(void) are not the same. void func() is equivalent to void func(...). (This is different from C++.)

You could try making sure the code is being compiled as C++ (if that's what you're actually intending), or if not just change your FuncPtr typedef to typedef void (*FuncPtr)(void).

brone
Thanks for answer. Unfortunatelly the code is compiled as C. I cannot change the FuncPtr. There should be possibility to change the function declaration rather.But what I believe is that some configuartion or gcc update (works with build 5484 for example) would help.
`void func();` is a prototype for a function accepting an unspecified, but fixed, number of arguments; `void func(...);` is a prototype for a function accepting a variable number of arguments.
pmg
But the declaration differ another way:void (*ptr)()void (*ptr)(void)which are imho both function w/o a paramter. There is no ... in declaration.
@Honza: In C (not C++), `void (*ptr)()` means "pointer to function taking unspecified arguments" while `void (*ptr)(void)` means "pointer to function taking no arguments". There is no switch for this; that's just the way C works. They will mean the same thing if you switch to C++.
ephemient
Now I understand. I'm ore familiar with C++ then C. Thanks.
A: 

There are two kinds of C, and it will get really confusing to mix them.


C compilers need to be backwards compatible because a lot of code was written in early C. It's possible to mix the two styles, but that can cause confusion and even runtime errors, because the rules are only consistent for programs that are entirely one style or entirely the other.

In legacy C ("K&R C") have things like: f(){/* stuff */} and

double f(d)
double d;
{ stuff }

A forward declaration in the legacy style might well use () even though it's really (d) because there was no way to specify the type, so little point in having a formal parameter.

And in C89- and C99-conforming style you have the familiar double f(double); for the declaration and double f(double d) { /* stuff */} for the definition. double f(void) is the ANSI way of doing it, but double f() is still "legal", but an unwise blend of the two language levels.

DigitalRoss
A: 

Yes, void func(void) is different from void func().

But any function pointer can be typecast into void (*)func() and back to its original type. So you could change the function pointer parameter's type in your C function.

Or you could just force the function pointer to be the right type with an explicit cast. On most systems, all function pointers smell the same, so even though it's not portable (or kosher), it should still work on most systems.

Loadmaster
Type-cast is what fixes the problem. Thanks for answers. There is no need for portability as the code is platform spacific (mac only).I can confirm that newer version then gcc 4.0.1 handles this well (or actually wrong). Not sure if it is just turned to a warning or completely ignored.