2010-09-28 46 views
6

Tôi có macro sau:C Preprocessor với câu lệnh if

#define IF_TRACE_ENABLED(level) if (IsTraceEnabled(level)) 

Mã người dùng nên xem xét sau đây:

IF_TRACE_ENABLED(LEVEL1) 
{ 
    ... some very smart code 
} 

Sự nhấn mạnh ở đây trên dấu ngoặc nhọn - Tôi muốn để ngăn chặn "nếu" từ macro để "ăn" mã khác:

if (...) 
    IF_TRACE_ENABLED(LEVEL1) 
     printf(....); 
else 
    bla bla bla 

Trong ví dụ này IF_TRACE_ENABLED "ăn" khối khác.

Có cách nào để thực thi mã người dùng không biên dịch mà không có hệ thống phanh xoăn hay có khác để xác định macro để đạt được sự an toàn?

+2

Tôi không thấy macro nào cung cấp cho bạn qua câu lệnh if nếu có. – JeremyP

+2

Quên về ví dụ này. Bạn có thể có một điều kiện phức tạp trong 'if' mà bạn không muốn lặp lại mỗi lần. –

+0

@JeremyP: không có nhiều tiện ích trong việc có macro cho ví dụ đơn giản này, nhưng như Nathan cho thấy có thể có sự phức tạp hơn trong macro gỡ lỗi và/hoặc có một số biến thể của macro dựa trên cấu hình xây dựng (cho ví dụ, một phiên bản phát hành luôn luôn đánh giá thành 'false' để các chuỗi dấu vết bị tước khỏi tệp thực thi). –

Trả lời

11

này không buộc người dùng của macro để sử dụng niềng răng, nhưng nó sẽ ngăn chặn một khoản else khỏi bị vô tình ăn:

#define IF_TRACE_ENABLED(level) if (!IsTraceEnabled(level)) {} else 

Một mặt lưu ý: niềng răng xung quanh printf() trong ví dụ thứ hai của câu hỏi sẽ không khắc phục được sự cố - số else được liên kết với bla bla bla sẽ vẫn bị ràng buộc với tuyên bố if trong macro.

+1

Đang cố gắng và không tìm ra cách có thể phản tác dụng. +1 –

+0

Nội dung của khối "if" được chuyển đến đâu? – dimba

+1

trong khối khác; câu trả lời hay! –

0

này nên làm việc, nhưng bạn sẽ phải vượt qua các nội dung của khối nếu như một đối số vĩ mô cũng như:

#define IF_TRACE_ENABLED(level,content) { if (IsTraceEnabled(level)) {content} } 
+0

Đây không phải là printf cần thiết (...). Đây có thể là bất kỳ mã nào chỉ nên được đánh giá khi điều kiện macro là đúng. – dimba

+0

Bạn nên thêm một khối xung quanh nội dung. –

+0

@Ronny - đây là những gì tôi muốn thực thi người dùng, vì vậy nếu anh ta quên làm điều đó, việc biên dịch sẽ thất bại – dimba

2

Bạn có thể thử này:

#define IF_TRACE_ENABLED(level) do { if(IsTraceEnabled(level)) { 
#define END_TRACE_ENABLED } } while(0); 

tôi không nghĩ rằng có bất kỳ cách nào để "thực thi" cú pháp tốt từ chỉ dòng mở của vĩ mô. Bạn sẽ cần phải sử dụng hai.

EDIT

Tôi đã thêm một cặp thêm niềng răng bên trong macro để tránh tất cả sự mơ hồ.

Để đối phó với những bình luận, macro này có nghĩa là để được sử dụng như thế này:

IF_TRACE_ENABLED(LEVEL1) 
    printf("Trace\n"); 
END_TRACE_ENABLED 

Không như một tuyên bố. Đối với hồ sơ, tôi nghĩ rằng đây là một sự lạm dụng của preprocessor và không ai nên làm điều này cả. Có gì sai khi chỉ viết nó ra, được gắn với #ifdef DEBUG nếu cần.

+0

Điều duy nhất tôi không thích trong giải pháp là thụt lề của khối giữa stat và dừng macro - biên tập viên của bạn sẽ không thụt lề nó. – dimba

+1

là nó không thể chỉ đơn giản là sử dụng niềng răng, mà không làm & trong khi? –

+0

@ptmato - có gì đó trong những gì @crypto nói. do/while được sử dụng để enfore macro trông giống như chức năng bình thường, bởi rằng anh ta thực thi sử dụng ";" đến cuối cùng. Vì thế ";" vào cuối macro là dư thừa. Bất kỳ cách nào chúng tôi không ";" vì macro không giống như một hàm gọi – dimba

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