¿Cómo sobrecargar funciones en C?

Oct 17 2020

Hay muchas publicaciones sobre este tema, pero no todas son para principiantes completos en programación C.

Es que tengo tres funciones:

struct model* createModel_empty(void);
struct model* createModel_single_value(double value);
struct model* createModel_single_value(const double* arr_value);

Y solo quiero usar la createModelfunción en mi código, que será sustituida por la implementación correcta.

De mi investigación en Internet y específicamente del desbordamiento de pila, entendí que hay dos opciones para hacer algo así:

  1. Use macros con _Generics& __ARGS_V__(no IDEA cómo implementar)
  2. Use macros con parámetros subrayados como foo(_1,_2,_3...), pero realmente no entiendo lo que significan esos guiones bajos

Por favor ayudame con este problema ;(

Respuestas

6 klutt Oct 18 2020 at 00:07

Hay muchas publicaciones sobre este tema, pero no todas son para principiantes completos en programación C

Simplemente porque estas técnicas no son adecuadas para principiantes. Por la misma razón, no encontrarás un tutorial para hacer malabares con 7 bolas que esté dirigido a personas que no pueden hacer malabares con tres.

Pero hay una solución bastante fácil, aunque voluminosa. Envuelva los datos en una estructura.

struct data {
    union {
        const double *p;
        double d;
    } data;
    int type;
};

struct model* createModel_single_value(struct data data) {
    switch(data.type) {
        case 0: return createModel_single_value_double(data.data.d);
        case 1: return createModel_single_value_const_double_ptr(data.data.p);
        default: return NULL;
    }
}

Tenga en cuenta que esta es una solución en tiempo de ejecución y no un tiempo de compilación que puede lograr con los métodos que mencionó. Esto puede hacer que sea propenso a un "comportamiento interesante" si no tiene cuidado, por lo que recomendaría estas precauciones:

Use un enumtipo for, por la única razón de que es más legible:

enum type { DOUBLE, CONSTDOUBLEPTR };

struct data {
    enum type type;
    ...

Y agregue afirma en las funciones de trabajo:

struct model* createModel_single_value_double(struct data data) {
    assert(data.type == DOUBLE);

Si realmente son un problema de rendimiento, puede eliminarlos más tarde. Lo más probable es que no lo sean.

Pero en general, le daría el consejo de que debe elegir un idioma que admita las funciones que necesita y, cuando haya elegido un idioma, utilícelo según lo previsto. No intente calzar con calzador cosas para las que no fue diseñado.

Abusar de un idioma puede ser muy divertido y también puede ayudarlo a obtener muchos conocimientos. Pero estas técnicas rara vez son muy útiles. Sin embargo, comprender cómo funcionan puede ser de gran ayuda en la depuración.