Pragma trong macro xác định


99

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

Tôi đang cố gắng đạt được điều 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 tăng cường (lưu cho wave) nếu có.


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

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

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

2
@James McNellis: Chỉ vì về mặt kỹ thuật, hầu hết các chương trình C đều có thể di chuyển sang C ++, không tạo ra chức năng thực sự phổ biến đó, vì không có lập trình viên C ++ nào làm được phần lớn nó. Hai ngôn ngữ thực sự không có nhiều điểm chung.
Puppy

Câu trả lời:


114

Nếu bạn đang sử dụng c99 hoặc c ++ 0x, có toán tử pragma, được 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 cuối cùng của ủy ban 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 -Echo

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

32
Là một FYI: MSVC có __pragma()toán tử tiền xử lý, điều này hơi khác một chút so với _Pragma()toán tử của C99 (C99 nhận một chuỗi ký tự, MSVC nhận các mã thông báo không có trong một chuỗi): msdn.microsoft.com/en-us/library/d9x1s805 .aspx
Michael Burr

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

5

Một điều thú vị mà bạn có thể làm với _Pragma ("đối số") là sử dụng nó để giải quyết một số vấn đề về trình biên dịch như

#ifdef _MSC_VER
#define DUMMY_PRAGMA _Pragma("argument")
#else
#define DUMMY_PRAGMA _Pragma("alt argument")
#endif

0

Không, không có cách nào di động để làm điều đó. Xin nhắc lại, không có cách di động nào để sử dụng #pragma cả. Do đó, nhiều trình biên dịch C / C ++ xác định các phương thức của riêng họ để thực hiện những thứ giống như pragma và chúng thường có thể được nhúng vào macro, nhưng bạn cần một định nghĩa macro khác trên mọi trình biên dịch. Nếu bạn sẵn sàng đi theo con đường đó, bạn thường sẽ làm những việc như sau:

#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 nó không rõ ràng, bạn muốn xác định Weak_bWeak_edưới dạng cấu trúc dấu ngoặc 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 dưới dạng phụ lục cho chữ ký kiểu và một số, như MSC thêm nó dưới dạng tiền tố (hoặc ít nhất là nó đã làm một lần, đã nhiều năm kể từ khi tôi sử dụng MSC). Có cấu trúc giằng cho phép bạn xác định một thứ gì đó 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 nó sang một trình biên dịch mà không có cá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 là cảnh báo hoặc tối ưu hóa pragmas, điều này có thể xảy ra. Trong các trường hợp khác, không quá nhiều.

Ồ, và tôi nghi ngờ rằng bạn thực sự cần định nghĩa Weak_b và Weak_e là các macro nhận tham số, nhưng tôi không sẵn sàng đọc qua các tài liệu để biết cách tạo định nghĩa yếu chỉ cho ví dụ này. Tôi để đó như một bài tập cho người đọc.


-3

có cách nào để nhúng câu lệnh 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 câu lệnh tiền xử lý. Tuy nhiên, bạn có thể đặt nó vào một inlinehàm. Tuy nhiên, điều đó đánh bại Cthẻ.


1
Đặt nó vào một hàm nội tuyến sẽ làm được 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ó inline, và hầu hết các triển khai C89 chính có một số biến thể.
Chris Lutz

@Chris Giả sử nhận xét của bạn nhắm vào tôi - quan điểm của bạn là - thì sao?

@Neil - Không, xin lỗi. Tôi đã chỉ đạo nó ở câu cuối cùng của @ sbi.
Chris Lutz

1
@Chris: À, inlinecòn một thứ nữa mà C vay mượn từ C ++! :)
sbi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.