tags:

views:

223

answers:

4

I want to make sure that a set of functions have the same signature in some C code. Ideally I would be able to define a new type that described the return value and arguments of a function and then declare my set of functions using this new type.

Additionally, is there a way to specify default values for the arguments to this function typedef?

+11  A: 
/* define a typedef for function_t - functions that return void */
/*      and take an  int and char parameter */

typedef void function_t( int param1, char param2);

/* declare some functions that use that signature */

function_t foo;
function_t bar;

Now when you define the functions there will be an error if they do not use the same signature as in the typedef.

void foo( int x, char c)
{
    /* do some stuff */

    return;
}

/* this will result in a compiler error */
int bar( int x, char c)
{
    /* do some stuff */

    return 1;
}


As for your new question (added 20 Oct 08): "Additionally, is there a way to specify default values for the arguments to this function typedef?"

No, there's no way to add default parameters to the typedef. Certainly not in C, which doesn't support default parameters at all. Even in C++ you can't do this because the default value of a parameter is not part of the type. In fact, a class that overrides a virtual method from a base class can specify a different value for a default parameter (or even remove the default altogether) - however, this is something that should not be done in general as it will simply cause confusion (http://www.gotw.ca/gotw/005.htm).

If you're using C++ you might be able to get the behavior you want using one of (or a combination of) the following:

  • abstract base classes
  • overloading
  • template functions
  • macros

But it would be difficult to suggest something without knowing more specifics about exactly what you're trying to accomplish. And I think it's likely that the result might well be pretty hacky.

Michael Burr
Wow, I've never then it that way, only as function pointer. Can you reuse that function_t also for the function definition?
quinmars
No, the definition has to use the full signature, but it must match.
Michael Burr
To clarify: use the typedef for the function prototypes, but declare the function definition normally. If the definition doesn't match the prototype, you'll get a compiler or linker error.
Adam Rosenfield
A: 

This is similar to how a function pointer works:

 // Declaration of function with int arg returning int
 typedef int (*CALLBACK)(int);

 //Definition
 int myFunc(int arg)
 {
     return 0;
 }

 // Function pointer usage
 CALLBACK pFunc = myFunc;
JayG
A: 

I don't think you can do this directly, but you could declare a function pointer type and then collect all your functions into an array. The compiler will let you know which ones don't match.

typedef void (*MethodSig)(int, int);

static MethodSig x[] = { fnA, fnB, ... };

Or use a macro to declare the function signature

#define MyFunc(X)  void X(int a, int b)

That way they will all be the same.

Rob Walker
A: 

You cannot really prevent anyone from making a function have any signature. But you can control what you will call. So I assume that is what you want.

Have the function that will call the arbitrary functions take a pointer to a function as a parameter. Since you mentioned typedef, you can define a typedef earlier in the program, like so:

Assume you only want functions of the signature "unsigned short id_for_allowed_functions (int x, char* y)":

typedef unsigned short (*id_for_allowed_functions)(int, char*);

Then, your calling function:

void calling_function (id_for_allowed_function x) { (*x)(3, "bla"); }

And to supply function foo to it:

unsigned short foo(int x, char* y) { /* ... */ }
calling_function(&foo);
mstrobl