2010-11-19 33 views
12

Trong mã bên dưới, ## làm gì?Hàm băm đôi (##) trong macro nghĩa là gì?

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

Về cơ bản một bản sao của [SO 1.489.932 C Preprocessor và Concatenation] (http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation/) –

Trả lời

22

## trong macro là nối. Tại đây, MAKE_TYPE(test) sẽ mở rộng tới: typedef int testId.

Từ 16.3.3 (Nhà điều hành ##):

Đối với cả hai đối tượng giống như và chức năng giống như invocations vĩ mô, trước khi danh sách thay thế được xem xét lại để biết thêm tên macro để thay thế, mỗi thể hiện của một ## tiền xử lý thẻ trong danh sách thay thế (không phải từ một cuộc tranh cãi ) sẽ bị xóa và trước tiền xử lý token được nối với những điều sau tiền xử lý thẻ

+4

tôi sẽ nhấn mạnh * đằng trước danh sách thay thế được xem xét lại *. Nếu bạn viết 'MAKE_TYPE (OBJECT (Foo))' thì bạn sẽ có 'typedef int OBJECT (Foo) Id;' ... rõ ràng là không hợp lệ. Đối phó với các macro là ... phức tạp, và tốt nhất nên tránh đặc biệt là đối với các trường hợp tầm thường như vậy mà nó chỉ làm xáo trộn mọi thứ. –

4

icecrime là chính xác, nhưng điều quan trọng cần chỉ ra trong định nghĩa là các mã thông báo cần phải là mã thông báo tiền xử lý hợp lệ. Ví dụ:

#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

Điều đó gây cho tôi rất nhiều thất vọng vài năm trước, vì tôi muốn nối ba thứ lại với nhau, và sự kết hợp của cả cặp đầu tiên lẫn cặp cuối cùng đều là các mã thông báo tiền xử lý hợp lệ. –

+0

Điểm tuyệt vời, nhưng không phải là câu trả lời. Nên có một bình luận cho icecrime của. –

Các vấn đề liên quan