Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

generic implementation in C

Hii ,

While I was implementing some of the programs for the class assignment, it just struck me how it would be to implement the same in a generic fashion using C.

I do know that we need to make use of the void pointers and functions but i was just stuck as to how to do it. Please give me an example that is simple and demonstrates the usage .

Like how to implement a comparison function to implement a comparison sort , or to insert into a linked list where each node has a element of varied type etc...

P.S : Any links to other questions or articles are helpful and welcome.

like image 405
Flash Avatar asked Nov 20 '10 12:11

Flash


1 Answers

Well, obviously one way to parametrize types is to use the preprocessor, e.g.:

#define DIVIDE_FUNC(type) divide_##type
#define DIVIDE_CALL(type, a, b) DIVIDE_FUNC(type)((a), (b))
#define DIVIDE_DECL(type) type DIVIDE_FUNC(type)(type a, type b)
#define DIVIDE_IMPLEMENTATION DIVIDE_DECL(DIVIDE_TYPE) { return a / b; }

#define DIVIDE_TYPE int
DIVIDE_IMPLEMENTATION
#undef DIVIDE_TYPE
#define DIVIDE_TYPE double
DIVIDE_IMPLEMENTATION

#include <stdio.h>

int main (void) {
    int i = 5, j = 2;
    (void) printf("int %d / %d = %d\n", i, j, DIVIDE_CALL(int, i, j));
    (void) printf("double %d / %d = %f\n", i, j, DIVIDE_CALL(double, i, j));
    return 0;
}

This implements two functions: divide_double and divide_int. In a more complex (realistic) example the implementation could be in a separate compilation file which is compiled (or included) separately for each type with a different DIVIDE_TYPE defined.

The downside compared to real generics is that the implementations for different types are not automatically generated, i.e. DIVIDE_CALL(mytype, x, y) does not cause the implementation for mytype to be generated. (Of course this could be arranged with some relatively simple scripting, but then one might argue that you are not really using C anymore and there are languages with prettier built-in generics. =)

In any case, this can work for data structures and such where the actual data type (not a void * pointer) is desired.

like image 161
Arkku Avatar answered Sep 20 '22 03:09

Arkku