2013-10-01 4 views
6

Nel mio codice ho un sacco di codice come:come passare il blocco come argomento della macro in ogg-c?

if (block) block(....) 

Quindi voglio definire una macro, qualcosa come

#define safetyCall(block, ...) if((block)) {block(##__VA_ARGS__)}; 

ma non ho potuto farlo funzionare. Qualche idea?

+0

se chiamo 'safetyCall (metodo, 0, newErr);' compilatore dicono: "incollare formato '(0', una pre-elaborazione di token non valido" e "Expected ';' dopo l'espressione " – jAckOdE

risposta

6

Non è necessario i ## ei ; problemi di trasloco:

#define safetyCall(block, ...) if((block)) { block(__VA_ARGS__); } 
+0

funziona perfettamente, molte grazie! – jAckOdE

+0

btw, quale diff tra' __VA_ARGS__' e '## __ VA_ARGS__' – jAckOdE

+1

@jAckOdE Il token' ##' è usato per "stringificare" gli argomenti (cioè trasformarli da 'x' in' "x" '). – trojanfoe

2

Questo può incorrere in problemi se il blocco è in linea e contiene il codice che ha una serie di stringhe separate da virgole, ecc

Esempio:.

safetyCall(^void() { 
    NSArray *foo = @[@"alice", "bob"]; 
}; 

Il compilatore si lamenta " '' atteso ']' o" e "identificativo atteso o '('"

Tuttavia, se si dichiara il blocco inline come blocco separato prima della macro, non verrà generato un errore.

Esempio:

void (^fooBlock)(void) = ^void() { 
    NSArray *foo = @[@"alice", @"bob"]; 
} 

safetyCall(fooBlock); 
+0

o semplicemente avvolgere il blocco tra parentesi – newacct

Problemi correlati