¿Se permiten definiciones de macros vacías en C? ¿Cómo se comportan?

3 minutos de lectura

Supongamos que la definición de macro “vacía”

#define FOO

¿Es válido el Estándar C? Si es así, ¿cuál es FOO después de esta definición?

  • Es una cadena vacía, y sí, es aceptable.

    – nhahtdh

    15 de diciembre de 2012 a las 12:30

  • Solo para señalar, aquí hay otra pregunta que involucra un uso interesante de definiciones vacías.

    – sidilio

    15 de diciembre de 2012 a las 12:40

avatar de usuario
zeta

Es simplemente una macro que se expande a, bueno, nada. Sin embargo, ahora que se ha definido la macro, puede consultar con #if defined (o #ifdef) si se ha definido.

#define FOO

int main(){
    FOO FOO FOO
    printf("Hello world");
}

se expandirá a

int main(){

    printf("Hello world");
}

Hay ciertas situaciones en las que esto resulta muy útil, por ejemplo, información de depuración adicional, que no desea mostrar en su versión de lanzamiento:

/* Defined only during debug compilations: */
#define CONFIG_USE_DEBUG_MESSAGES

#ifdef CONFIG_USE_DEBUG_MESSAGES
#define DEBUG_MSG(x) print(x)
#else
#define DEBUG_MSG(x) do {} while(0)
#endif

int main(){
    DEBUG_MSG("Entering main");
    /* ... */
}

Desde la macro CONFIG_USE_DEBUG_MESSAGES ha sido definido, DEBUG_MSG(x) se expandirá a print(x) y obtendrás Entering main. Si quitas el #define, DEBUG_MSG(x) se expande a un vacío dowhile bucle y no verá el mensaje.

  • Esto es muy arriesgado, ya que puede interrumpir la compilación, especialmente. cuando tienes declaraciones como if (x) DEBUG_MSG("test"); else DEBUG_MSG("test");. Prefiero declarar mi macro vacía con una declaración sin efecto como #define DEBUG_MSG(x) do {} while(0)

    – Ely

    24 de febrero de 2017 a las 8:55


  • @Ely ¿Por qué se rompería eso? Si DEBUG_MSG fue definido como #defined DEBUG_MSG(x) luego else DEBUG_MSG("test") simplemente se convierte else ; lo cual es válido porque ; es la ‘sentencia vacía’.

    – Farap

    5 mayo 2018 a las 23:43

  • A veces hago algo así: #define NOTHING Entonces cosas como int NOTHING main()

    usuario12211554

    17 de julio de 2019 a las 21:58

  • @Ely ¿Por qué se rompería eso? ¿Por qué no solo {}?

    – endolito

    27 de agosto de 2021 a las 18:57

avatar de usuario
md5

Sí, el estándar permite la definición vacía.

C11 (n1570), § 6.10 Directivas de preprocesamiento

control-line:
   # define identifier replacement-list new-line
   # define identifier lparen identifier-list(opt) ) replacement-list new-line
   # define identifier lparen ... ) replacement-list new-line
   # define identifier lparen identifier-list , ... ) replacement-list new-line
replacement-list:
    pp-tokens(opt)

Una utilización común son los protectores de inclusión.

#ifndef F_H
# define F_H

#endif

  • No has respondido cuál es el valor de FOO después de definir vacío.

    usuario1150105

    15 de diciembre de 2012 a las 12:45

  • @ user14284 Las macros no tienen valores. Se expanden a una lista de tokens. Esta lista puede estar vacía.

    – melpomene

    15 de diciembre de 2012 a las 12:47

Las definiciones de macros vacías también se pueden utilizar para la autodocumentación. los IN en el fragmento de código a continuación hay una muestra. Tanto el código como el comentario se citan del proyecto EDK II.

//
// Modifiers for Data Types used to self document code.
// This concept is borrowed for UEFI specification.
//

///
/// Datum is passed to the function.
///
#define IN


typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_RESET)(
  IN EFI_BLOCK_IO_PROTOCOL          *This,
  IN BOOLEAN                        ExtendedVerification
  );

  • Yo usaría otro ejemplo. No tiene que ser una cita del código real, pero el ejemplo actual contiene una gran cantidad de información innecesaria. (Por cierto, asegúrese de que su respuesta aún responda a la pregunta original; funciona bien con las otras respuestas, pero como respuesta independiente, realmente no se ajusta a la pregunta “¿Qué significa?” FOO expandir a”?).

    – Zeta

    11 de agosto de 2015 a las 14:14

  • Gracias por mencionarlo. Simplemente estoy leyendo este fragmento de código cuando veo esta pregunta. Dado que la respuesta se eligió hace mucho tiempo, solo espero que mi respuesta pueda servir como referencia educativa.

    – smwikipedia

    11 de agosto de 2015 a las 14:48

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad