Uso de paréntesis en declaraciones de preprocesador de definición

2 minutos de lectura

Uso de parentesis en declaraciones de preprocesador de definicion
Chrusciki

Así que me preguntaba cuándo se debe usar

 #define xxx (yyy)

contra

 #define xxx  yyy

Mi proyecto incluye archivos que tienen sus propias definiciones, como AD0_ADMD_CT, si quisiera redefinirlos, ¿tendría que usar (AD0_ADMD_CT) o solo AD0_ADMD_CT en la definición o no?

AD0_ADMD_CT se define como

 #define    AD1_ADMD_CT     (IO_AD1.ADMD.bit.CT)

Entonces sería cualquiera

#define AD0_COMPARETIME     (AD0_ADMD_CT)

o

#define AD0_COMPARETIME     AD0_ADMD_CT

No hay diferencia en ambos. en primer caso XXX es reemplazado por yyy y por (yyy) es el segundo caso. La convención para usar corchetes es evitar errores lógicos que puedan ocurrir. Por ejemplo, define la función de suma como:

#define f(N) N+N 
int a = f(5)*f(5)  

El valor esperado es 10*10 = 100, pero la salida es 35 porque en el momento de la compilación se convierte en

int a = 5+5*5+5, entonces, usando la regla de preferencia del operador, la salida cambia.

Así que los paréntesis evitan este tipo de errores.

Al agregar paréntesis, está obligando a que el argumento dentro de los paréntesis se evalúe antes que el resto del cuerpo de la macro, por lo que si tuviera

#define MULT(x, y) (x) * (y)
// now MULT(3 + 2, 4 + 2) will expand to (3 + 2) * (4 + 2)

No parece afectar su caso actual a menos que haya más en sus macros.

Es muy importante si tiene operadores en su macro. Por ejemplo:

#define ADD(x,y) x + y
ADD(1,2) * 3 /* Should be 9, is 7 */

Debiera ser:

#define ADD(x,y) (x + y)
ADD(1,2) * 3 /* 7 */

Estos problemas de precedencia también se aplican a los argumentos, como dice @Gi Joe, y deben incluirse entre paréntesis para la precedencia.

Sin embargo, para una macro como:

#define MAGICNUM 3

No importa.

Una cosa importante a recordar es que el preprocesador simplemente expande las macros. Por ejemplo, si tuviera las siguientes líneas:

#define AD0_COMPARETIME_1    (AD0_ADMD_CT)
#define AD0_COMPARETIME_2    AD0_ADMD_CT

num_1 = AD0_COMPARETIME_1;
num_2 = AD0_COMPARETIME_2;

Después de la primera expansión tendrías esto:

num_1 = (AD0_ADMD_CT);
num_2 = AD0_ADMD_CT;

Y después de la segunda expansión tendrías esto:

num_1 = ((IO_AD1.ADMD.bit.CT));
num_2 = (IO_AD1.ADMD.bit.CT);

Puede surgir un problema, como se indica en otras respuestas, cuando se expande una expresión.

¿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