¿Podemos eliminar paréntesis alrededor de los argumentos en las definiciones de macros C?
c-preprocessor parentheses (2)
Este es un ejemplo relativamente tonto, pero tiene un resultado diferente:
#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)
#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)
#define s1 "foo", "blah"
int main() {
Streq(s1, "blah"); // Compiles and compares equal.
MyStreq(s1, "blah"); // Compiler error. Too many parameters.
}
Desde http://c-faq.com/style/strcmp.html , aprendí la siguiente macro de conveniencia:
#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)
Quiero saber por qué se usan tantos paréntesis en esta macro. ¿Funciona cada paréntesis para un propósito o esta macro usa paréntesis redundantes que no sirven para nada?
¿Podemos eliminar los paréntesis alrededor de s1
y s2
y crear una macro como esta?
#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)
La macro MyStreq
parece funcionar para mí tan bien como Streq
.
#include <string.h>
#include <stdio.h>
#define Streq(s1, s2) (strcmp((s1), (s2)) == 0)
#define MyStreq(s1, s2) (strcmp(s1, s2) == 0)
int main()
{
printf("%d %d/n", Streq("foo", "foo"), MyStreq("foo", "foo"));
printf("%d %d/n", Streq("fox", "foo"), MyStreq("fox", "foo"));
printf("%d %d/n", Streq("foo", "fox"), MyStreq("foo", "fox"));
return 0;
}
Salida del código de arriba:
1 1
0 0
0 0
¿Se imagina el uso de estas macros donde Streq
hace lo que cabría esperar, pero MyStreq
no lo hace?
Los paréntesis a veces importan, y es una buena idea insertarlos incondicionalmente. Considere la siguiente macro pobre:
#define OP(a, b) (a * b) /* BAD */
Invocado como OP(x + 1, y + 1)
se expandirá a x + 1 * y + 1, rompiendo la agrupación deseada. Los paréntesis evitan este problema.
Si lee una definición de macro con paréntesis alrededor de cada uso de argumento, el autor seguramente tuvo este problema en mente, incluso si esos parens son redundantes para esa macro.