1

I have a C program in which I need to create a whole family of functions which have the same signatures and bodies, and differ only in their types. What I would like to do is define a macro which generates all of those functions for me, as otherwise I will spend a long time copying and modifying the original functions. As an example, one of the functions I need to generate looks like this:

int copy_key__sint_(void *key, void **args, int argc, void **out {
if ((*out = malloc(sizeof(int))) {
return 1;
}

**((_int_ **) out) = *((_int_ *) key);  
return 0;  

}

The idea is that I could call a macro, GENERATE_FUNCTIONS("int", "sint") or something like this, and have it generate this function. The italicized parts are what need to be plugged in.

Is this possible?

4 Answers 4

2

I don't understand the example function that you are giving very well, but using macros for the task is relatively easy. Just you wouldn't give strings to the macro as arguments but tokens:

#define DECLARE_MY_COPY_FUNCTION(TYPE, SUFFIX)              \
int copy_function_ ## SUFFIX(unsigned count, TYPE* arg)

#define DEFINE_MY_COPY_FUNCTION(TYPE, SUFFIX)               \
int copy_function_ ## SUFFIX(unsigned count, TYPE* arg) {   \
 /* do something with TYPE */                               \
 return whatever;                                           \
}

You may then use this to declare the functions in a header file

DECLARE_MY_COPY_FUNCTION(unsigned, toto);
DECLARE_MY_COPY_FUNCTION(double, hui);

and define them in a .c file:

DEFINE_MY_COPY_FUNCTION(unsigned, toto);
DEFINE_MY_COPY_FUNCTION(double, hui);

In this version as stated here you might get warnings on superfluous `;'. But you can get rid of them by adding dummy declarations in the macros like this

#define DEFINE_MY_COPY_FUNCTION(TYPE, SUFFIX)               \
int copy_function_ ## SUFFIX(unsigned count, TYPE* arg) {   \
 /* do something with TYPE */                               \
 return whatever;                                           \
}                                                           \
enum { dummy_enum_for_copy_function_ ## SUFFIX }
Sign up to request clarification or add additional context in comments.

Comments

2

Try something like this (I just tested the compilation, but not the result in an executed program):

 #include "memory.h"

   #define COPY_KEY(type, name)                                 \
   type name(void *key, void **args, int argc, void **out) { \
      if (*out = malloc(sizeof(type))) {                     \
         return 1;                                           \
      }                                                      \
   **((type **) out) = *((type *) key);                      \
   return 0;                                                 \
   }                                                         \

COPY_KEY(int, copy_key_sint)

For more on the subject of generic programming in C, read this blog wich contains a few examples and also this book which contains interesting solutions to the problem for basic data structures and algorithm.

Comments

1

That should work. To create copy_key_sint, use copy_key_ ## sint.

If you can't get this to work with CPP, then write a small C program which generates a C source file.

Comments

0

Wouldn't a macro which just takes sizeof(*key) and calls a single function that uses memcpy be a lot cleaner (less preprocessor abuse and code bloat) than making a new function for each type just so it can do a native assignment rather than memcpy?

My view is that the whole problem is your attempt to apply C++ thinking to C. C has memcpy for a very good reason.

3 Comments

@R.: I don't think this is answer to the question of the OP. I understand that code that he is giving as just one type of example of what kind of declarations he wants to achieve.
I think my answer applies to a large category of situations for which one might want "C++ templates for C". Often if you realize you can treat the data as an abstract byte array, or partly as such with a callback function for processing it (as in qsort, etc.), you're able to write much simpler and more efficient C code.
Does memcpy have a Windows implementation?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.