2010-11-19 11 views
12

W poniższym kodzie, co robi ##?Co oznacza podwójny skrót (#) w makrze?

#define MAKE_TYPE(myname) \ 
typedef int myname ## Id; \ 
+0

zasadzie kopią [SO 1489932 preprocesora C i konkatenacji] (http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation/) –

Odpowiedz

22

## w makro jest konkatenacją. Tutaj MAKE_TYPE(test) rozszerzy się do: typedef int testId.

Od 16.3.3 (Operator ##):

Dla obu obiektowy jak i funkcja makro podobnych inwokacji, zanim lista wymiana jest ponownie zbadana dla więcej nazw makr do zastąpienia, każdy instancji ## przerób tokena liście zastępczej (nie z argument) zostaje usunięte, a poprzedzającym wyprzedzającego znacznik jest łączone z następujących przerób tokena

+4

że chciałby podkreślić * przed lista wymiany jest ponownie sprawdzana *. Jeśli napiszesz 'MAKE_TYPE (OBJECT (Foo))' będziesz miał 'typedef int OBJECT (Foo) Id;' ... który jest oczywiście nieważny. Radzenie sobie z makrami jest ... skomplikowane, a najlepiej unikane, szczególnie w tak trywialnych przypadkach, w których tylko zaciemniają rzeczy. –

4

icecrime jest poprawny, ale ważne jest, aby podkreślić, że tokeny muszą być ważnymi tokeny preprocessingu. Przykłady:

#define CONCAT(a,b) a ## b 
CONCAT(ClassyClass, <int>); // bad, <int> is not a valid preprocessing token 
CONCAT(Symbol, __LINE__); // valid as both are valid tokens 
+1

To spowodowało wiele frustracji kilka lat temu, ponieważ chciałem połączyć trzy rzeczy razem, a kombinacja ani pierwszej, ani ostatniej pary nie była poprawnymi żetonami preprocesingu. –

+0

Świetny punkt, ale nie odpowiedź. Powinien być komentarzem do icecrime. –