I'm trying to achieve method overloading in C, preferably using macros so the header/library can handle the definitions and declarations instead of putting that onto the user. Now I've read this answer about using _Generic however the problem is my functions have struct types. So there's no way to evaluate their type using a __typeof__ of _Generic. I wonder if there is any way at all.
This is how my header file looks like (which is all we should be concerned with)-
#pragma once
// Macros for generic like use of the data structure
// Macros for the stack type itself
/*
 * Define stack with corresponding type
 * Converts Stack(int) to intstack_t
*/
#define Stack(type) type stack_t
// Macros for functions
/*
 * Define createStack function
 * Converts createStack(int, 5) to create_intstack(5)
*/
#define createStack(type, capacity) create_ ##type ##stack(capacity)
/*
 * Define destroyStack function
 * Converts destroyStack(someIntStack) to destroy_intstack(someIntStack)
 * Where someIntStack is a pointer to a variable of type intstack_t
*/
#define destroyStack(stack) _Generic(stack, intstack_t*: destroy_intstack, charstack_t*: destroy_charstack)(stack)
/*
 * Define push function
 * Converts push(someIntStack, data) to intstack_push(someIntStack, data)
 * Where someIntStack is a pointer to a variable of type intstack_t
*/
#define push(stack, data) _Generic(stack, intstack_t*: intstack_push, charstack_t*: charstack_push)(stack, data)
// Stack structure definition(s)
// int stack definition
typedef struct IntegerStack {
    int top;
    unsigned capacity;
    int* arr;
}intstack_t;
// char stack definition
typedef struct CharacterStack {
    int top;
    unsigned capacity;
    char* arr;
}charstack_t;
//Stack functions
// int stack functions
intstack_t* create_intstack(int);
void destroy_intstack(intstack_t*);
void intstack_push(intstack_t*, int);
// char stack functions
charstack_t* create_charstack(int);
void destroy_charstack(charstack_t*);
void charstack_push(charstack_t*, char);
Majority of the function declarations (and indirectly, their respective macros) have been removed, as they all essentially function the same. I'm only concerned about the push function macro as provided. The other macros are really there to show what kind of usecase I intend. Obviously the macro used in push using _Generic will not work as intstack_t or charstack_t are not primitive types.
The goal is for the user to be able to use push(stack, data) where the stack can be a variable of either type intstack_t* or charstack_t* and the statement push(stack, data) will be transformed into intstack_push(stack, data) or charstack_push(stack, data) respectively.
 
    