X-Macros en C

Las X-Macros se basan en la propiedad de las macros anidadas y la capacidad de definir macros dentro de otras macros. X-Macros es una técnica de preprocesador muy poderosa en el sentido de que puede crear una pieza de código automantenida e interdependiente . Cuando el cambio de una parte de un programa conduce a un cambio en otra parte, se dice que el código es interdependiente.

Sintaxis:
una aplicación de macro X consta de dos partes:

  • La definición de los elementos de la lista:
    #define VARIABLES \
        X(value1, 1)  \
        .
        .
        .  \
        X(valueN, N)
    
  • Expansión(es) de la lista para generar fragmentos de declaraciones o enunciados:
    #define X(name) int name;
        VARIABLES
    #undef X
    

La lista está definida por un macro o archivo de encabezado (llamado VARIABLES) que no genera código por sí mismo, sino que simplemente consiste en una secuencia de invocaciones de una macro (clásicamente llamada “X”) con los datos de los elementos. Cada expansión de VARIABLES está precedida por una definición de X con la sintaxis de un elemento de lista. La invocación de VARIABLES expande X para cada elemento de la lista.

Implementaciones:

  • Ejemplo 1: El siguiente código explica el funcionamiento de X-Macros:

    #include <stdio.h>
      
    // Defines four variables.
    #define VARIABLES \
        X(value1, 1)  \
        X(value2, 2)  \
        X(value3, 3)  \
        X(value4, 4)
      
    // driver program.
    int main(void)
    {
        // Declaration of every variable
        // is done through macro.
        #define X(value, a) char value[10];
            VARIABLES
        #undef X
          
        // String values are accepted
        // for all variables.
        #define X(value, a) scanf("\n%s", value);
            VARIABLES
        #undef X
          
        // Values are printed.
        #define X(value, a) printf("%d) %s\n", a, value);
            VARIABLES
        #undef X
        return 0;
    }
    Producción:

    1) geeks
    2) for
    3) geeks
    4) geeksforgeeks
    

    En el código anterior, la adición de una o más variables en la macro «VARIABLES» conducirá a su declaración automática, escaneando e imprimiendo. Este simple ejemplo aclara el funcionamiento y la potencia de X-Macros. Después de la expansión, el código anterior se verá como el siguiente código:

    #include <stdio.h>
      
    int main(void)
    {
        char value1[10];
        char value2[10];
        char value3[10];
        char value4[10];
      
        scanf("\n%s", value1);
        scanf("\n%s", value2);
        scanf("\n%s", value3);
        scanf("\n%s", value4);
      
        printf("%d) %s\n", 1, value1);
        printf("%d) %s\n", 2, value2);
        printf("%d) %s\n", 3, value3);
        printf("%d) %s\n", 4, value4);
        return 0;
    }
    Producción:

    1) geeks
    2) for
    3) geeks
    4) geeksforgeeks
    

    Aunque el código anterior simplemente explica el poder de X-Macros, dicho uso es raro y no se recomienda porque hace que el código sea menos legible. Un ejemplo más práctico es con tablas de enumeración o salto.

  • Ejemplo 2: El siguiente código explica el funcionamiento de X-Macros con enumeración:

    #include <stdio.h>
      
    // Defining a macro 
    // with the values of colors.
    #define COLORS \
        X(RED)     \
        X(BLACK)   \
        X(WHITE)   \
        X(BLUE)
      
    // Creating an enum of colors
    // by macro expansion.
    enum colors {
        #define X(value) value,
            COLORS
        #undef X
    };
      
    // A utility that takes the enum value
    // and returns corresponding string value
    char* toString(enum colors value)
    {
        switch (value) {
            #define X(color) \
                case color:  \
                    return #color;
                    COLORS
            #undef X
        }
    }
      
    // driver program.
    int main(void)
    {
        enum colors color = WHITE;
        printf("%s", toString(color));
        return 0;
    }
    Producción:

    WHITE
    

    En el código anterior, cualquier adición o eliminación de cualquier constante de la macro COLORS se reflejará automáticamente en la definición de enumeración, así como en la función toString(). Es por eso que las X-Macros se utilizan para producir códigos automantenidos. Después de la expansión de la macro, el código anterior se verá como el siguiente código:

    #include <stdio.h>
      
    // Creating an enum of colors.
    enum colors {
        RED,
        BLACK,
        WHITE,
        BLUE
    };
      
    /*A utility that takes the enum value and returns 
    corresponding string value*/
    char* toString(enum colors value)
    {
        switch (value) {
        case RED:
            return "RED";
        case BLACK:
            return "BLACK";
        case WHITE:
            return "WHITE";
        case BLUE:
            return "BLUE";
        }
    }
      
    // driver program.
    int main(void)
    {
        enum colors color = WHITE;
        printf("%s", toString(color));
        return 0;
    }
    Producción:

    WHITE
    

Ventajas de X-Macros

  • Las X-Macros se utilizan ampliamente en el desarrollo de sistemas operativos mediante la creación de archivos de encabezado separados para facilitar el mantenimiento y la legibilidad.
  • Ayuda a mantener fácilmente la programación compleja
  • puede crear una pieza de código autosuficiente e interdependiente

Desventajas de X-Macros

  • El código se vuelve menos legible.
  • El código es complejo de entender.
  • Comúnmente utilizado solo para programación interna, como la programación del sistema operativo.

Referencia: https://en.wikipedia.org/wiki/X_Macro

Publicación traducida automáticamente

Artículo escrito por archit16bit1025 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *