2009-08-20 7 views
21

¿Cómo implemento macro no operativa en C++?¿Cómo implemento macro (o plantilla) no operativa en C++?

#include <iostream> 

#ifdef NOOP  
    #define conditional_noop(x) what goes here? 
#else  
    #define conditional_noop(x) std::cout << (x) 
#endif 
int main() {  
    conditional_noop(123); 
} 

Quiero que esto no haga nada cuando se define NOOP e imprime "123", cuando NOOP no está definido.

+3

Si usa msvc, el intrínseco '__noop' ​​debería ser de su interés, y a diferencia de algunas de las soluciones presentadas, no obtendrá algo así como un cuelgue accidental else – Necrolis

Respuesta

21

Como se mencionó anteriormente antes - nada
Además, hay un error de impresión en su código.
debe ser #else no #elif. si es #elif que es ser seguido por la nueva condición

#include <iostream> 

#ifdef NOOP  
    #define conditional_noop(x) do {} while(0) 
#else  
    #define conditional_noop(x) std::cout << (x) 
#endif 

Diviértete codificación! EDITAR: agregó la construcción [do] para la robustez como se sugiere en otra respuesta.

+9

lo anterior es incorrecto. si tiene conditional_noop dentro de un bloque de control no rodeado por llaves. Vea la solución de avakar por la forma robusta que siempre funcionará. – Vitali

+0

de acuerdo, gracias! – Andrew

12

La definición de la macro para ser void transmite su intención bien.

#ifdef NOOP 
    #define conditional_noop(x) (void)0 
#else 
+6

Debería tener' (void) 0' puesto que '(void);' es un error de compilación – Motti

+1

Gracias, corregido. 15char –

13
#ifdef NOOP  
    #define conditional_noop(x) 
#elif 

nada!

+0

No pude compilarlo de esta manera. El problema es que utilicé #elif en lugar de #else. Ahora lo tengo bien. Gracias. –

+0

tienes razón ... Acabo de copiar eso de tu ejemplo. – Toad

5

Puede dejarlo en blanco. No necesita seguir el #define con nada.

1

Como se trata de una macro, también se debe considerar un caso como

if (other_cond) 
    conditional_noop(123); 

para estar en el lado seguro, le puede dar una sentencia vacía como

#define conditional_noop(X) {} 

de la tercera edad C a veces se necesita definir la declaración vacía de esta manera (también debe optimizarse):

#define conditional_noop(X) do {} while(0) 
+5

El truco 'do-while' no tiene nada que ver con la edad del compilador. – avakar

+4

Usted no entendió la razón detrás de usar 'do {} while (0)' y, en consecuencia, su primer código no es suficiente y no funcionaría. Para ver por qué, imagine que su código de ejemplo anterior tenía una rama 'else' ... –

48

Si bien dejarlo en blanco es la opción obvia, me gustaría ir con

#define conditional_noop(x) do {} while(0) 

Este truco es, obviamente, no-op, pero le obliga a tener un punto y coma después de conditional_noop(123).

+1

¡Respuesta útil para mí! En mi caso, necesité no hacer algunas impresiones en el kernel). Para cualquiera que esté buscando aquí, para hacer un argumento variable macro noop, uno puede hacer '#define conditional_noop (x, ...) do {} while (0)' –

+0

Esto dejará un compilador advirtiendo que la expresión es constante. – Mo0gles

+0

@ Mo0gles, en msvc lo hará, aunque me sorprende que sea el primero en quejarse :) Tenemos esta advertencia deshabilitada por este motivo. – avakar

4

Como han dicho otros, déjelo en blanco.

Un truco que puedes usar es agregar (void)0 a la macro, lo que obliga a los usuarios añadir un punto y coma después de que:

#ifdef NOOP  
    #define conditional_noop(x) (void)0 
#else  
    #define conditional_noop(x) std::cout << (x); (void)0 
#endif 

En C++, (void)0 no hace nada. This article explains otras opciones no tan buenas, así como la razón detrás de ellas.

+3

Al tener dos instrucciones en la segunda macro, es posible que también haya obligado a los usuarios a utilizar llaves cuando de otro modo no serían necesarias, y olvidar las llaves puede o no tener un efecto en el programa. Las preguntas frecuentes a las que se ha vinculado explican cómo evitar ese problema. –

6
#ifdef NOOP 
    static inline void conditional_noop(int x) { } 
#else 
    static inline void conditional_noop(int x) { std::cout << x; } 
#endif 

Usando función en línea vacío permite la comprobación de tipos, incluso cuando NOOP no está definido. Por lo tanto, cuando NOOP no está definido, aún no podrá pasar una estructura a esa función, o una variable indefinida. Esto eventualmente evitará que obtenga errores de compilación cuando active el indicador NOOP.

+1

+1 para la única (hasta ahora, de todos modos) solución que no usa una macro. Pero, ¿para qué es el "estático"? ¿Y no sería mejor hacer de esto una plantilla para que no solo acepte 'int'? – sbi

+1

La estática elimina los errores del vinculador si la definición existe en un archivo de encabezado que se incluye en varios archivos .cpp. Cambiarlo a una función de plantilla funcionaría bien, pero eso eliminaría la verificación de tipo (especialmente cuando se define NOOP, ya que no se hace nada con x). – moswald

0

creo que una combinación de las variantes anteriores es una buena solución:

#ifdef NOOP 
    static inline void conditional_noop(int x) do {} while(0) 
#else 
    static inline void conditional_noop(int x) do { std::cout << x; } while(0) 
#endif 

Lo bueno es que estos dos códigos difieren sólo dentro de un bloque, lo que significa que su comportamiento para el exterior es completamente idéntico para el analizador.

+0

Te das cuenta de que es una función, no una macro, ¿verdad? –

Cuestiones relacionadas