Macros de preprocesador de varias líneas


81

¿Cómo hacer una macro de preprocesador de varias líneas? Sé cómo hacer una línea:

#define sqr(X) (X*X)

pero necesito algo como esto:

#define someMacro(X)
    class X : public otherClass
    {
         int foo;
         void doFoo();
    };

¿Cómo puedo hacer que esto funcione?

Este es solo un ejemplo, la macro real puede ser muy larga.


Puede obtener fácilmente la respuesta buscando el SO. por ejemplo, stackoverflow.com/questions/4007865/…
Forever Learner

diferentes métodos están aquí: parashift.com/c++-faq/macros-with-multi-stmts.html
Ayrat

Respuestas:


123

Se utiliza \como carácter de escape de continuación de línea.

#define swap(a, b) {               \
                       (a) ^= (b); \
                       (b) ^= (a); \
                       (a) ^= (b); \
                   }

EDITAR: Como @abelenky señaló en los comentarios, el \carácter debe ser el último carácter de la línea . Si no es así (incluso si es solo un espacio en blanco después), obtendrá mensajes de error confusos en cada línea posterior.


44
Una advertencia: asegúrese de que \ sea el último carácter de la línea. En C, el espacio en blanco normalmente no importa, pero en este caso, el espacio en blanco invisible al final de la línea puede matarte.
abelenky

2
Sin embargo, se debe agregar que el texto resultante está en una línea. Debido a que C trata todos los espacios en blanco entre tokens de la misma manera, generalmente no importa mucho, pero aún así.
Peter - Reincorpora a Monica

Otra cosa que sugeriría hacer es colocar ` after all useful lines of the macro, and add a comment afterward saying something like // Línea en blanco requerida después de la macro . It's sometimes easier to ensure that all lines of a macro end with `que para asegurarse de que todas las líneas menos la última lo hagan .
supercat

No sabía que podía usar el xor bit a bit de esa manera para intercambiar variables, ¡pero desearía haberlo tenido!
cmarangu

18

Puede hacer que una macro abarque varias líneas colocando una barra invertida ( \) al final de cada línea:

#define F(x) (x)   \
              *    \
             (x)

18

TENGA EN CUENTA que como señalaron Kerrek SB y coaddict, que debería haber sido señalado en la respuesta aceptada, SIEMPRE coloque llaves alrededor de sus argumentos. El ejemplo sqr es el ejemplo simple que se enseña en los cursos de CompSci.

Aquí está el problema: si lo define de la forma en que lo hizo, ¿qué sucede cuando dice "sqr (1 + 5)"? Obtienes "1 + 5 * 1 + 5" o 11.
Si colocas correctamente los tirantes, #define sqr(x) ((x)*(x))
obtienes ((1 + 5) * (1 + 5)) o lo que queríamos 36 ... hermoso.

Ed S. va a tener el mismo problema con 'swap'


¿qué tal sqr(++i)? (supongamos que tenemos un int i) :)
Géza Török

Lo hice como ejercicio y aparentemente ise incrementa a medida que se sustituye en la macro (en este caso se sustituye dos veces), luego se multiplica. Así quesqr(++5) == ((7) * (7))
jiveturkey

2
@ GézaTörök La expansión de sqr(++i)to ((++i)*(++i))invocaría un comportamiento indefinido porque el valor de ise modifica más de una vez dentro de esa declaración (sin punto de secuencia entre las operaciones).
moooeeeep

5

Debe escapar de la nueva línea al final de la línea escapándose con un \:

#define sqr(X) \
        ((X)*(X))
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.