c++ - que - ¿Es incorrecto agregar directivas de preprocesador en una macro de función similar?
ejemplos de macro en c++ (2)
Sé que mi pregunta es similar a esta o a esta , pero me parece que no es realmente lo mismo y, más aún, la segunda no acepta una respuesta. Decidí preguntar si era correcto agregar directivas de preprocesador cuando se llama una macro de función?
En mi caso tengo una macro similar a la función:
#define FUNC_MACRO(a, b) // do something with the variables
y en algún lugar del código lo llamo con diferencia específica si se define alguna otra macro:
// ...
FUNC_MACRO(aVal
#ifdef ANOTHER_MACRO
+ offset
#endif // ANOTHER_MACRO
, bVal);
// ...
Probé en mi máquina (Linux, con gcc 4.8) y funcionó bien (con y sin las directivas de preprocesador, y con y sin ANOTHER_MACRO definido), pero ¿es seguro hacerlo?
Leí el párrafo 16.3 / 9 de la respuesta de la primera pregunta similar, pero ¿también es cierto para mi caso?
Haga lo siguiente en su lugar?
#ifdef ANOTHER_MACRO
FUNC_MACRO(aVal + offset, bVal);
#else
FUNC_MACRO(aVal, bVal);
#endif
EDITAR: abordar las preocupaciones planteadas por los comentarios; No sé si el método del OP es específicamente incorrecto (creo que otras respuestas lo cubren). Sin embargo, la concisión y la claridad son dos aspectos que se consideran bastante importantes cuando se codifica con C.
Como tal, preferiría encontrar mejores formas de lograr lo que el PO parece estar intentando, repensando ligeramente la situación que he ofrecido anteriormente. Supongo que el OP puede haber usado un ejemplo de trivia, pero normalmente encuentro que la mayoría de las situaciones C hacen que si algo se vuelve demasiado complejo o intenta hacer algo que no parece que el lenguaje debería permitir, entonces hay mejores formas de lograr lo que se necesita .
El lenguaje C deja esto como un comportamiento indefinido en 6.10.3. Reemplazo de macro, ¶11 :
Si hay secuencias de tokens de preprocesamiento dentro de la lista de argumentos que de otro modo actuarían como directivas de preprocesamiento, el comportamiento no está definido.
De hecho, está mal hacerlo.
GCC y quizás otras compilaciones populares no lo captan, que es probablemente la razón por la que muchos usuarios del lenguaje no son conscientes. Me encontré con esto cuando parte de mi código no pudo compilarse en PCC (y rápidamente arregló el error en mi código).
Actualización: PJTraill preguntó en los comentarios sobre un caso en el que sería "engañoso o sin sentido" tener directivas de preprocesador dentro de una macro expansión. Aquí hay uno obvio:
foo(a, b,
#ifdef BAR
c);
#else
d);
#endif
No estoy seguro de si hubiera sido plausible para el lenguaje especificar que los condicionales balanceados del preprocesador dentro de la expansión de la macro están bien, pero creo que también se encontrarían con problemas con ambigüedades en el orden en que deberían procesarse.