2012-02-24 45 views
6

Tôi muốn một cái gì đó như:C/C++ #define Macro bên trong macro?

#define C_OR_CPP(C__, CPP__) #ifdef __cplusplus\ 
CPP__\ 
#else\ 
C__\ 
#endif 

Có thể không? Có thể một số hack bẩn với #include?

Lý do: Tôi tạo tiêu đề trong đó cấu trúc sử dụng biến thành viên loại vector<stuff>*, nhưng trong C tôi muốn nó đơn giản là void*, bạn biết đấy.

TIA

+6

Yo Dawg, tôi nghe bạn thích macro ? – Gui13

+0

@ Gui13 Xin lỗi, nhưng hai bạn muốn gì? Làm cách nào khác để bạn sử dụng tiêu đề trong C++ và C? – imacake

+1

@imacake: xin lỗi, tôi vừa tạo một tham chiếu không đáng kể tới [meme internet] (http://knowyourmeme.com/memes/xzibit-yo-dawg). Không có vi phạm để được thực hiện :-) – Gui13

Trả lời

11

vấn đề với

#ifdef __cplusplus 
#define C_OR_CPP(C, CPP) CPP 
#else 
#define C_OR_CPP(C, CPP) C 
#endif 

(Rời tên với dấu gạch dưới đôi để thực hiện mỗi phresnel nhận xét)

+0

Đây là cách nó được thực hiện trong mọi trường hợp tôi đã thấy. Ví dụ, mẫu này được sử dụng để xác định macro cho 'WEAK' (nghĩa là định nghĩa hàm đã cho có thể được thay thế bằng định nghĩa khác có cùng tên trong một đơn vị biên dịch khác, thay vì dừng liên kết với lỗi đa định nghĩa) tùy thuộc vào trình biên dịch được sử dụng (ví dụ: gcc hoặc IAR hoặc Keil). –

+0

Chỉ cần hoàn hảo ..! – imacake

1

Không có trong C++. Nhưng bạn có thể

#ifdef __cplusplus 
# define CPP 
#else 
# define C 
#endif 

Tôi cho rằng đây chỉ là ví dụ về bệnh lý của bạn. Cũng lưu ý rằng dấu gạch dưới kép được dành riêng cho người triển khai thư viện (xem 17.6.4.3.2 Tên chung).

vector , nhưng trong C tôi muốn đơn giản là vô hiệu, bạn biết đấy.

Vì vậy, những gì nói chống lại một giải pháp như

struct Foo { 
    #ifdef __cplusplus 
    ... 
    #else 
    ... 
    #endif 
}; 

hoặc những gì nói chống lại cung cấp các API khác nhau cho các ngôn ngữ lập trình khác nhau?

+0

Bạn có nghĩa là, 'CPP' trong ví dụ của bạn sẽ là' vector * 'và' C' sẽ là 'void *'? Đó là tốt, havent nghĩ về nó. Sẽ xem xét nó trong trường hợp không có giải pháp khác được tìm thấy. – imacake

+0

** Các API khác nhau **: KHÔNG. Tôi đang thực sự làm việc trên một chương trình với tất cả mọi thứ believ trên thế giới xuất phát từ một quy tắc, và nên đơn giản hóa đối với nó (có triết lý trong nhiều năm trong đầu của tôi, bây giờ viết một chương trình cho phù hợp với nó). (** ví dụ về giải pháp **): Trông rất ô uế và khó đọc hơn. Tại sao không hỏi về một cái gì đó tốt hơn? = D – imacake

+0

@imacake: Tôi đang bối rối về quy tắc, điều này có liên quan gì đến C so với C++? –

1

AProgrammer đã đưa cho bạn câu trả lời đúng, nhưng câu trả lời cho "là nó có thể" là gì một phần của câu hỏi là không. Việc mở rộng macro không xảy ra cho đến khi tất cả các chỉ thị tiền xử lý đã được xử lý, vì vậy mọi macro mở rộng thành #define hoặc #ifdef sẽ được chuyển tới trình biên dịch dưới dạng văn bản nguồn thông thường, điều này sẽ khiến trình biên dịch bị hỏng.

0

Tiếng Anh của tôi kém và tôi xin lỗi vì lỗi ngôn ngữ và lỗi chính tả nếu có.

Nếu #ifdef không được bao bọc lệnh gọi macro, có một giải pháp không quá duyên dáng.

g ++ chỉ: Bạn có thể thử điều này trong những dịp chọn lọc. Nhưng nếu có dấu phẩy trong a hoặc b, cách giải quyết vẫn cần thiết. Nó đơn giản dựa trên thực tế là __cplusplus được định nghĩa là "1" khi ở trong môi trường C++ và vẫn giữ nguyên trong khi không.

#define SELECT1(a, b) a 
#define SELECT__cplusplus(a, b) b 
#define xcat(a,b) a##b 
#define concat(...) xcat(__VA_ARGS__) 
#define C_OR_CPP(C, CPP) concat(SELECT, __cplusplus)(C, CPP) 

C_OR_CPP(1, 2) 

môi trường khác Kiểm tra vĩ mô __cplusplus, một trình biên dịch rằng comforming tiêu chuẩn C++ nên tạo

#define __cplusplus value 

và giá trị nên> = 199711L

+0

Không chắc chắn điều này thêm vào câu trả lời được chấp nhận bởi @AProgrammer –