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?
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?
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 do
–while
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
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
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