2009-05-29 25 views

Trả lời

131

Bạn có thể theo dõi nó bằng dấu chấm phẩy và làm cho nó trông giống như một hàm. Nó cũng hoạt động với các mệnh đề if/else đúng cách.

Nếu không có thời gian (0), mã của bạn ở trên sẽ không làm việc với

if (doit) 
    INIT_LIST_HEAD(x); 
else 
    displayError(x); 

kể từ dấu chấm phẩy sau khi vĩ mô sẽ "ăn" mệnh đề khác, và ở trên sẽ thậm chí không biên dịch.

+5

Nhưng câu hỏi của OP đứng. Tại sao không chỉ {(ptr) -> next ...} thay vì làm {(ptr) -> next ...} trong khi (0) ;? –

+26

arno giải thích điều đó. Nó sẽ mở rộng thành "{(ptr) -> tiếp theo ...};" do đó, một tuyên bố theo sau là một tuyên bố thứ hai. Tuy nhiên, nếu cú ​​pháp là "if (expression) statement statement khác". Người khác sẽ không được liên kết với bất kỳ nếu, vì bạn đã viết "if (expression) tuyên bố tuyên bố" (một "{...}" và một ";" tuyên bố). –

+3

Như Amo đã nói, đó là một thủ thuật thông minh cho phép macro có * là * một câu lệnh C phải kết thúc bằng dấu chấm phẩy. Nó làm cho hành vi macro giống hệt như một cuộc gọi hàm, cho đến khi việc xây dựng câu lệnh và kết thúc (với ';') được quan tâm. – Eddie

41

Nó cho phép bạn nhóm nhiều câu lệnh thành một macro.

Giả sử bạn đã làm một cái gì đó như:

if (foo) 
    INIT_LIST_HEAD(bar); 

Nếu macro được định nghĩa mà không có sự Encapsulating làm {...} while (0) ;, các mã trên sẽ mở rộng tới

if (foo) 
    (bar)->next = (bar); 
    (bar)->prev = (bar); 

Điều này rõ ràng không phải là những gì đã được dự định, vì chỉ có tuyên bố đầu tiên sẽ được thực hiện nếu foo nắm giữ. Câu lệnh thứ hai sẽ được thực hiện bất kể foo có giữ.

Chỉnh sửa: Hơn nữa giải thích tại http://c-faq.com/cpp/multistmt.htmlhttp://developer.apple.com/documentation/DeveloperTools/gcc-4.0.1/cpp/Swallowing-the-Semicolon.html#Swallowing-the-Semicolon

+7

Điều này không giải thích được .. trong khi (0) một phần của macro, chỉ cần sử dụng {} niềng răng. – SPWorley

+0

do {} trong khi (0) phần được giải thích trong bài đăng này là một trong hai. – adobriyan

+1

SPWorley, adobriyan: Trên thực tế, có vẻ như tác giả của bài đăng này đã thêm liên kết giải thích do {} khi (0). – Jamer

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