I need to implement some methods that do stuff with different kinds of number arrays. Usually, I'd use generics for that job, but as C doesn't provide them, I'm now trying to emulate them using macros.
Here's an example of what I'm trying to do:
#ifndef TYPE #define TYPE int #endif TYPE get_minimum_##TYPE (TYPE * nums, int len){ TYPE min = nums[0]; for (int i = 1; i < len; i++) { if (nums[i] < min) { min = nums[i]; } } return min; }
However, this won't compile. The clang error message:
error: expected ';' after top level declarator
Is there any way to do this in C? Or do I need implement this for every type by hand?
Generics are syntax components of a programming language that can be reused for different types of objects. Typically, generics take the form classes or functions, which take type(s) as a parameter.
Generics is the idea to allow type (Integer, String, … etc and user-defined types) to be a parameter to methods, classes and interfaces. For example, classes like an array, map, etc, which can be used using generics very efficiently.
Genericity is one of the most powerful means for obtaining flexibility in programming with statically typed programming languages. Genericity constructs take on very different forms, the choice of which has a considerable impact on expressiveness, modularity, static checkability and efficiency properties of programs.
C does not have static templates, but you can use macros to emulate them.
You can do something like this in a header file:
// // generic.h // #define TOKENPASTE(x, y) x ## y #define GET_MINIMUM(T) TOKENPASTE(get_minimum_, T) TYPE GET_MINIMUM (TYPE) (TYPE * nums, size_t len){ TYPE min = nums[0]; for (size_t i = 1; i < len; i++) { if (nums[i] < min) { min = nums[i]; } } return min; }
and then #include
it in a source file for each required type, e.g.:
// // generic.c // #define TYPE int #include "generic.h" #undef TYPE #define TYPE float #include "generic.h" #undef TYPE
You can test this by running it through the preprocessor:
$ gcc -E generic.c int get_minimum_int (int * nums, size_t len){ int min = nums[0]; for (size_t i = 1; i < len; i++) { if (nums[i] < min) { min = nums[i]; } } return min; } float get_minimum_float (float * nums, size_t len){ float min = nums[0]; for (size_t i = 1; i < len; i++) { if (nums[i] < min) { min = nums[i]; } } return min; }
Actually, the best you can do is to define a macro that will generate the function for the given type.
#define define_get_minimum(T) \ T get_minimum_##T(T* nums, int len){ \ T min = nums[0]; \ for (int i = 1; i < len; i++) { \ if (nums[i] < min) { \ min = nums[i]; \ } \ } \ return min; \ }
Then, you can call that macro to define the specializations you need (with C++ template, a similar thing is done automagically by the compiler).
define_get_minimum(int) define_get_minimum(double) define_get_minimum(float)
Another thing that a C++ compiler does automagically is deduce the overloaded function you need. You can't have that in C, so you will have to tell you are using the it specialization. You can simulate a template-like syntax for your function with the following macro (the C++ <>
are just replaced by ()
):
#define get_minimum(T) get_minimum_##T
Then, you should be able to call it the following way:
int main() { // Define arr as char* array... // Do stuff... int res = get_minimum(int)(arr, 3); }
I did not test this code, but it should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With