Reputation: 48128
Say I have a function which I want to call based on the size of a type.
Is there some way this can be done using a macro?
static int array_find_index_4_impl(void *array, const unsigned int arr_len, const void *var)
{
const int32_t *arr_step = arr;
unsigned int i;
for (i = 0; i < arr_len; i++, arr_step++) {
if (*arr_step == *(int32_t *)var) {
return (int)i;
}
}
return -1;
}
static int array_find_index_2_impl(void *array, const unsigned int arr_len, const void *var)
{
const int16_t *arr_step = arr;
unsigned int i;
for (i = 0; i < arr_len; i++, arr_step++) {
if (*arr_step == *(int16_t *)var) {
return (int)i;
}
}
return -1;
}
/* etc... for other sizes too */
#define array_find_index(array, array_len, var) \
array_find_index_##SOME_MAGIC_SIZEOF(*array)##_impl(array, array_len, var)
I know C11's _Generic
can be used to check for specific types, but I was interested in ignoring the exact types and finding the right function based on size only.
Another option could be to store a lookup table of functions, eg:
#define array_find_index(array, var) \
array_find_index_fn_table[sizeof(*array)](array, var)
Which can work but would prefer to construct the identifier directly if possible.
Of course its possible to pass the sizeof
to a function and use memcmp
, but I'm interested to know if about creating identifiers from a structs size
Upvotes: 4
Views: 106
Reputation: 1
Another possible solution could be to generate some X-macro header file with the size of the relevant types, i.e. to generate a file like
#define MY_SIZEOF_int 4
etc etc.... using some simple C generating file containing
#define WANT_SIZE(Typ) { \
printf("#define MY_SIZEOF_%s %d\n", \
#Typ, (int) sizeof(Typ)); };
and have somewhere
WANT_SIZE(int)
WANT_SIZE(my_struct_t)
and running the specialized generator in the build process...
assuming some typedef struct my_struct_st my_struct_t
before (because this works only for simply named types).
Of course, this requires complexifying the building procedure (e.g. add a couple of rules and targets in your Makefile
...)
Yet another solution could be to use (with GCC...) its __builtin_type_compatible_p
or even customize it (by adding your specific pragmas or builtins) using MELT.
Upvotes: 2
Reputation: 40145
#include <stdio.h>
#include <string.h>
static int array_find_index(const void *array, const void *value, size_t numOfMember, size_t element_size){//option add compare function
size_t i;
const char *p = (const char *)array;
for(i = 0; i < numOfMember; ++i, p += element_size){
if(memcmp(p, value, element_size)==0)
return (int)i;
}
return -1;
}
#define ARRAY_FIND_INDEX(array, var) \
array_find_index(array, var, sizeof(array)/sizeof(*array), sizeof(*array))
int main (void){
int ia[] = {1,2,3,4,5};
int ikey = 3;
int index = ARRAY_FIND_INDEX(ia, &ikey);
printf("%d\n", index);
char ca[] = {'1','2','3','4','5'};
char ckey = '5';
index = ARRAY_FIND_INDEX(ca, &ckey);
printf("%d\n", index);
ckey = '0';
index = ARRAY_FIND_INDEX(ca, &ckey);
printf("%d\n", index);
return 0;
}
Upvotes: -1
Reputation: 106
I have a function which I want to call based on the size of a type. Is there some way this can be done using a macro?
Using only macros, no it can't be done. Macros are expended by the preprocessor, there is no awareness of an identifier's type at this stage, let alone its size. In other words the preprocessor just doesn't have the information needed to do what you want.
However, a solution to the original problem of having a function called based on the size of a type could of course involve some preprocessing, like the one you proposed.
Upvotes: 0