2010-01-16 27 views
8

tôi đã nhận thấy rằng đôi khi, C macro được viết như một cái gì đó như thế này:Thông tin thêm về `({});` trong C?

#define foo(bar) ({ ++bar; }) 

Sau một số thử nghiệm, tôi đã phát hiện ra rằng:

  1. ({}); sẽ biên dịch, nhưng không làm gì cả. (Như mong đợi.)
  2. Rời khỏi ; tắt sẽ gây ra lỗi cú pháp. Một tác dụng phụ của điều này là đảm bảo rằng foo() trông giống như một hàm trong mã của bạn. (Mặc dù, nếu bạn để dấu chấm phẩy tắt, lỗi không phải là rất hữu ích để chẩn đoán vấn đề!)
  3. return ({}); than phiền về giá trị khoảng trống không bị bỏ qua, giống như tôi đã cố gắng sử dụng hàm void.

Đây có phải chỉ là để làm cho nhà phát triển thêm dấu chấm phẩy vào macro của họ hay nó có mục đích khác? Tôi đã thử Google, nhưng nó thất bại thảm hại với dấu chấm câu. có phải có một cái tên cho thứ này?

Trả lời

8

Đây là phần mở rộng của GNU có tên là statement expressions.

Khi khai báo macro trong tiêu chuẩn C, bạn thường thấy do...while(0) vòng được sử dụng cho các mục đích tương tự (ví dụ: tạo phạm vi khối). Một biểu thức tuyên bố là vượt trội hơn vòng lặp hack vì nó có thể trả về một giá trị. Nếu bạn muốn làm một cái gì đó tương tự trong tiêu chuẩn-C, bạn sẽ phải xác định một chức năng bổ sung và mất sự tiện lợi của phạm vi từ vựng.

2

() là một biểu thức. ({code; code;}) là một câu lệnh ghép bên trong một biểu thức. Đó là phần mở rộng GNU C.

http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html

EDIT: wow, tôi đã liên kết từ Google và không để ý đó là vì gcc 2,95 lần đầu tiên. Xưa!

+0

Cũ - nhưng cú pháp vẫn được hỗ trợ trong 4.4.2. –

3

Điều thú vị về biểu thức câu lệnh (nếu có điều thú vị) là câu lệnh cuối cùng là kết quả của biểu thức.

#define foo(bar) ({ ++bar; 3.1415927; }) 

int i = 0; 
float pi = foo(i); 
Các vấn đề liên quan