¿Por qué cada archivo .h comienza con #ifndef #define #endif? Ciertamente podemos compilar el programa sin esas directivas.En C y C++, ¿por qué cada archivo .h generalmente está rodeado por las directivas #ifndef #define #endif?
Respuesta
Es un llamado "incluir guardia". El objetivo es evitar que el archivo tenga que analizarse varias veces si se incluye varias veces.
Y para evitar múltiples definiciones de la misma clase. – James
¿Alguna vez hubo una directiva #import, o es solo mi imaginación? –
@Autopulated: Eso es lo que quiere decir al analizar varias veces. Hay más cosas que las redefiniciones de clase de las que preocuparse; todos están encapsulados por "análisis múltiple". – GManNickG
Se llama protector de inclusión. Puede escribir sin ellos hasta que comience a escribir programas grandes y descubra que necesita incluir el mismo archivo .h más de una vez, directa o indirectamente, desde un archivo .c. Luego, sin incluir guardias, obtendría múltiples errores de definición, pero con ellos, los contenidos del archivo de encabezado se analizan solo una vez y se omiten todas las veces subsiguientes, evitando esos errores. Es una buena práctica usarlos siempre.
Impide inclusiones múltiples de un solo archivo. El mismo se puede hacer usando
#pragma once
Directiva, pero esos son estándar #ifndefs por lo tanto el apoyo de cada compilador.
#pragma una vez. Es una extensión específica del compilador. –
... pero es ampliamente compatible, para ser justos –
Si un archivo de encabezado contiene una definición como
int i;que, al estar varias veces sin guardián, producirá un error de compilación.
ifndef comprueba que alguna variable de preprocesador no está definida (y no lo está, por primera vez), luego la define explícitamente para evitar ser capturada nuevamente. En MSVC también puede usar
#pragma onceen lugar de
ifndef
.
Si entiendo correctamente, desea saber si, a falta de guardias incluidas, puede incluir un archivo de encabezado varias veces causar un error o comportamiento peligroso. Esto es después de excluir múltiples definiciones, etc.
Imagine un programador malicioso, cuyo archivo de cabecera no tiene los guardias de inclusión. Su archivo de encabezado define una macro, SZ
, que es un tamaño que usa para las matrices asignadas estáticamente. El programador podría escribir su archivo de cabecera de esta manera:
#ifndef SZ
#define SZ 1024
#else
#if SZ == 1024
#undef SZ
#define SZ 128
#else
#error "You can include me no more than two times!"
#endif
#endif
Ahora, si se incluye el archivo de cabecera una vez, se obtiene SZ
igual a 1024. Si se incluye dos veces, se convierte en SZ
128. Por supuesto, la mayor parte real los programadores del mundo no son maliciosos, y nadie escribe código como el anterior.
Nota que el estándar C permite assert.h
para ser #include
d más de una vez con un comportamiento diferente dependiendo de si NDEBUG
se define en el momento de la inclusión de assert.h
. Por lo tanto, assert.h
no puede haber incluido guardias. Esa es una característica, no un error, sin embargo.
- 1. ¿Por qué #ifndef y #define se usan en archivos de encabezado C++?
- 2. C: ¿Son globales las directivas #define?
- 3. ¿Por qué debería eliminar las directivas innecesarias de C#?
- 4. El compilador de Old C se atora en #ifndef #define
- 5. ¿Por qué utilizar encabezados precompilados (C/C++)?
- 6. C macro/# define indentación?
- 7. Propósito de #ifndef FILENAME .... # endif en el archivo de encabezado
- 8. MinGW no define WIN32, error en las directivas de preprocesador
- 9. ¿Por qué palabra clave "paquete" y .h?
- 10. Directiva de preprocesador #ifndef para C/C++ código
- 11. ¿por qué no se recomienda utilizar directivas en C++?
- 12. ¿Cuál es eficiente usar #pragma una vez o #ifndef #endif?
- 13. ¿Qué significan las extensiones de archivo .c y .h para C?
- 14. compilador de C# Directivas
- 15. Android Galaxy Tab: ¿Por qué el ícono de lanzamiento está rodeado por un borde rosado?
- 16. ¿Por qué la macro 'max' se define así en C?
- 17. ¿Definir estructuras autorreferenciales en un archivo de encabezado C (.h)?
- 18. Cómo detectar LLVM y su versión a través de las directivas #define?
- 19. #include in .h o .c/.cpp?
- 20. Alternativas al uso de "#define" en C++? ¿Por qué está mal visto?
- 21. ¿Por qué usar archivos .cpp si puedo tener todo mi código C++ en el archivo .h?
- 22. ¿Es posible que las macros del preprocesador C contengan directivas de preprocesador?
- 23. Recomendar C front-end que conserva las directivas de preprocesador
- 24. ¿Por qué el programa general generalmente comienza en 0x8000?
- 25. Unicode - generalmente trabajando con él en C++
- 26. ¿Por qué no está firmado mi ensamblaje en C++?
- 27. ¿Por qué C# vincula las variables locales por adelantado?
- 28. ¿Por qué usa Forth IF ENTONCES ... en lugar de ENDIF?
- 29. Directivas de preprocesador múltiple en una línea en C++
- 30. Cómo forzar la sangría de las directivas condicional C#?
Google "incluye guardias" –