2010-06-12 37 views
76

Có cách nào để nhúng tuyên bố pragma trong macro với các câu lệnh khác không?Pragma trong định nghĩa macro

tôi đang cố gắng để đạt được một cái gì đó như:

#define DEFINE_DELETE_OBJECT(type)      \ 
    void delete_ ## type_(int handle);     \ 
    void delete_ ## type(int handle);            \ 
    #pragma weak delete_ ## type_ = delete_ ## type 

tôi không sao với các giải pháp thúc đẩy (tiết kiệm cho sóng) nếu có.

+5

Có thể cho rằng nó không phải là - #pragmas không được xác định theo tiêu chuẩn C hoặc C++. –

+0

Bộ tiền xử lý là, ngay cả khi tiểu ban được phép cụ thể mà anh ta muốn chạy không phải là. – Puppy

+0

@DeadMG: Có rất nhiều điều rất phổ biến giữa C và C++. Trong khi tiền xử lý là _mostly_ phổ biến, có sự khác biệt lớn trong cách tiền xử lý được chỉ định tùy thuộc vào tiêu chuẩn ngôn ngữ nào đang được sử dụng (C89, C99, C++ và C++ 0x FCD). –

Trả lời

94

Nếu bạn đang sử dụng c99 hoặc C++ 0x có các nhà điều hành pragma, sử dụng như

_Pragma("argument") 

tương đương với

#pragma argument 

ngoại trừ nó có thể được sử dụng trong macro (xem phần 6.10.9 của tiêu chuẩn c99, hoặc 16.9 của dự thảo ủy ban cuối cùng C++ 0x)

Ví dụ:

#define STRINGIFY(a) #a 
#define DEFINE_DELETE_OBJECT(type)      \ 
    void delete_ ## type ## _(int handle);     \ 
    void delete_ ## type(int handle);     \ 
    _Pragma(STRINGIFY(weak delete_ ## type ## _ = delete_ ## type)) 
DEFINE_DELETE_OBJECT(foo); 

khi đưa vào gcc -E cho

void delete_foo_(int handle); void delete_foo(int handle); 
#pragma weak delete_foo_ = delete_foo 
; 
+29

Là một FYI: MSVC có toán tử tiền xử lý '__pragma()', không may là hơi khác so với toán tử '_Pragma()' của C99 (C99 lấy một chuỗi ký tự, MSVC lấy các thẻ không nằm trong chuỗi): http://msdn.microsoft.com/en-us/library/d9x1s805.aspx –

+10

@MichaelBurr MSVC luôn phải khác biệt, phải không? – Thomas

-3

có cách nào để nhúng tuyên bố pragma trong macro với các câu lệnh khác không?

Không, bạn không thể đặt câu lệnh tiền xử lý vào báo cáo tiền xử lý. Tuy nhiên, bạn có thể đặt nó vào một hàm inline. Tuy nhiên, điều đó đánh bại thẻ C.

+1

Điều gì tốt sẽ đặt nó vào một chức năng nội tuyến làm gì? Các chỉ thị tiền xử lý được xử lý trước bất kỳ thứ gì có thể nhận ra một hàm. –

+2

C99 có 'nội tuyến' và hầu hết các triển khai C89 chính đều có một số biến thể. –

+0

@Chris Giả sử nhận xét của bạn hướng đến tôi - quan điểm của bạn là - cái gì? –

0

Không, không có cách nào để thực hiện điều đó. Sau đó, một lần nữa, không có cách nào để sử dụng #pragma. Bởi vì điều này, nhiều trình biên dịch C/C++ định nghĩa các phương thức riêng của chúng để thực hiện những thứ giống như pragma, và chúng thường có thể được nhúng trong các macro, nhưng bạn cần một định nghĩa macro khác nhau trên mọi trình biên dịch. Nếu bạn sẵn sàng để đi con đường đó, bạn thường kết thúc làm công cụ như thế này:

#if defined(COMPILER_GCC) 
#define Weak_b 
#define Weak_e __attribute__((weak)) 
#elif defined(COMPILER_FOO) 
#define Weak_b __Is_Weak 
#define Weak_e 
#endif 

#define DEFINE_DELETE_OBJECT(type)      \ 
    Weak_b void delete_ ## type_(int handle) Weak_e; \ 
    Weak_b void delete_ ## type(int handle) Weak_e;  

Trong trường hợp của nó không rõ ràng bạn muốn xác định Weak_bWeak_e như cấu trúc bracketing bắt đầu và kết thúc bởi vì một số trình biên dịch như GCC thêm các thuộc tính như là một phụ lục cho một chữ ký loại, và một số, như MSC thêm nó như là một tiền tố (hoặc ít nhất nó đã làm một lần, năm của nó kể từ khi tôi đã sử dụng MSC). Việc có các kết nối khung cho phép bạn định nghĩa một cái gì đó luôn luôn hoạt động, ngay cả khi bạn phải chuyển toàn bộ chữ ký kiểu vào một cấu trúc trình biên dịch. Tất nhiên, nếu bạn thử chuyển sang trình biên dịch mà không có thuộc tính bạn muốn, bạn không thể làm gì ngoài việc để các macro mở rộng thành không có gì và hy vọng mã của bạn vẫn chạy. Trong trường hợp hoàn toàn cảnh báo hoặc tối ưu hóa pragmas, điều này có khả năng. Trong các trường hợp khác, không quá nhiều. Ồ, và tôi nghi ngờ bạn thực sự cần phải định nghĩa Weak_b và Weak_e làm macro tham số, nhưng tôi không sẵn sàng đọc qua tài liệu về cách tạo định nghĩa yếu cho ví dụ này. Tôi để nó như một bài tập cho người đọc.

4

Một điều tốt đẹp bạn có thể làm với _Pragma ("tranh luận") là sử dụng nó để đối phó với một số vấn đề biên dịch như

#ifdef _MSC_VER 
#define DUMMY_PRAGMA _Pragma("argument") 
#else 
#define DUMMY_PRAGMA _Pragma("alt argument") 
#endif 
Các vấn đề liên quan