visual una programación programacion para nombre macro lenguaje guardar ejecutar comandos celda carpeta avanzado archivo c macros c-preprocessor ifndef

una - manual 400 macros para excel pdf



¿Por qué solo definir una macro si aún no está definida? (7)

Como dije en el comentario, imagine esta situación:

foo.h

#define FOO 4

defs.h

#ifndef FOO #define FOO 6 #endif #ifndef BAR #define BAR 4 #endif

bar.c

#include "foo.h" #include "defs.h" #include <stdio.h> int main(void) { printf("%d%d", FOO, BAR); return 0; }

Imprimirá 44 .

Sin embargo, si el ifndef condicional no estaba allí, el resultado serían advertencias de compilación de la redefinición de MACRO e imprimirá 64 .

$ gcc -o bar bar.c In file included from bar.c:2:0: defs.h:1:0: warning: "FOO" redefined [enabled by default] #define FOO 6 ^ In file included from bar.c:1:0: foo.h:1:0: note: this is the location of the previous definition #define FOO 4 ^

En toda nuestra base de código C, veo cada macro definida de la siguiente manera:

#ifndef BEEPTRIM_PITCH_RATE_DEGPS #define BEEPTRIM_PITCH_RATE_DEGPS 0.2f #endif #ifndef BEEPTRIM_ROLL_RATE_DEGPS #define BEEPTRIM_ROLL_RATE_DEGPS 0.2f #endif #ifndef FORCETRIMRELEASE_HOLD_TIME_MS #define FORCETRIMRELEASE_HOLD_TIME_MS 1000.0f #endif #ifndef TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS #define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS 50.0f #endif

¿Cuál es la razón de hacer estas comprobaciones de definición en lugar de solo definir las macros?

#define BEEPTRIM_PITCH_RATE_DEGPS 0.2f #define BEEPTRIM_ROLL_RATE_DEGPS 0.2f #define FORCETRIMRELEASE_HOLD_TIME_MS 1000.0f #define TRIMSYSTEM_SHEARPIN_BREAKINGFORCE_LBS 50.0f

No puedo encontrar esta práctica explicada en ninguna parte de la web.


Cualquier proyecto C reside en múltiples archivos fuente. Cuando se trabaja en un solo archivo fuente, las comprobaciones parecen (y en realidad) no tienen sentido, pero cuando se trabaja en un proyecto C grande, es una buena práctica verificar las definiciones existentes antes de definir una constante. La idea es simple: necesita la constante en ese archivo fuente específico, pero puede que ya esté definido en otro.


Esto le permite anular las macros cuando está compilando:

gcc -DMACRONAME=value

Las definiciones en el archivo de encabezado se utilizan como valores predeterminados.


Esto se hace para que el usuario del archivo de encabezado pueda anular las definiciones de su código o del indicador -D del compilador.


No conozco el contexto, pero esto se puede usar para dar al usuario la disponibilidad de anular los valores establecidos por esas definiciones de macro. Si el usuario define explícitamente un valor diferente para cualquiera de esas macros, se utilizará en lugar de los valores utilizados aquí.

Por ejemplo, en g ++ puede usar el indicador -D durante la compilación para pasar un valor a una macro.


Podría pensar en un marco / biblioteca que le da al usuario un valor predeterminado que le permita compilar y trabajar en él. Esas definiciones se extienden en diferentes archivos y se recomienda al usuario final que incluya su archivo config.h donde puede configurar sus valores. Si el usuario olvidó alguna definición, el sistema puede continuar funcionando debido a la configuración predeterminada.


Utilizando

#ifndef BEEPTRIM_PITCH_RATE_DEGPS #define BEEPTRIM_PITCH_RATE_DEGPS 0.2f #endif

permite al usuario definir el valor de la macro usando el argumento de la línea de comando (en gcc / clang / VS) -DBEEPTRIM_PITCH_RATE_DEGPS=0.3f .

Hay otra razón importante. Es un error redefinir una macro de preprocesador de manera diferente. Vea esta respuesta a otra pregunta SO . Sin la comprobación #ifndef , el compilador debería producir un error si -DBEEPTRIM_PITCH_RATE_DEGPS=0.3f se utiliza como argumento de línea de comando en la invocación del compilador.