2012-06-11 31 views
5

Hãy xem xét những điều sau C chương trình (bỏ qua các vấn đề tác dụng phụ kép):mở rộng Macro cho các macro với đối số so với các biến có cùng tên

#define max(a, b) (a>b?a:b) 

int main(void){ 
    int max = max(5,6); 
    return max; 
} 

Các GCC tiền xử lý biến này vào:

int main(void){ 
    int max = (5>6?5:6); 
    return max; 
} 

Điều này khá hay vì bạn không phải lo lắng về những va chạm không chủ ý giữa maxmax(). Số GCC manual cho biết:

Macro giống như chức năng chỉ được mở rộng nếu tên của nó xuất hiện với một cặp dấu ngoặc sau nó. Nếu bạn chỉ viết tên, nó được để lại một mình

Đây có phải là tiêu chuẩn hóa hay chỉ là một cái gì đó được thực hiện theo quy ước?

Trả lời

5

Có, hành vi ở đây được xác định rõ.

Macro của bạn max là macro giống chức năng (tức là khi bạn xác định nó, tên của nó được theo sau bởi dấu ngoặc đơn bên trái và nó lấy đối số).

Việc sử dụng max sau trong mã của bạn chỉ là lời gọi của macro đó nếu sử dụng max được theo sau bởi dấu ngoặc đơn bên trái. Vì vậy, những sẽ không gọi max vĩ mô:

int max; 
max = 42; 

Nhưng những tất cả sẽ gọi vĩ mô tối đa:

max(1, 2) 
max (1, 2) 
max 
(
    1, 2 
) 
max() 

(Lưu ý rằng dòng cuối cùng là vô hình thành bởi vì số lượng các đối số không khớp với số lượng tham số. Tuy nhiên, đây vẫn là lời gọi macro và sẽ gây ra lỗi biên dịch.)

Hành vi này được bắt buộc bởi tiêu chuẩn ngôn ngữ C. C99 §6.10.3/10 tiểu bang rằng sau một macro chức năng giống như đã được xác định,

Mỗi trường hợp tiếp theo của tên macro chức năng giống như theo sau là một ( như tiền xử lý thẻ tiếp theo giới thiệu chuỗi các thẻ tiền xử lý được thay thế bằng danh sách thay thế trong định nghĩa (một lệnh gọi macro).

+0

Tôi đang bối rối. Có vẻ như gcc đã vinh danh macro tối đa và thay vào đó không gọi hàm tối đa thực. – octopusgrabbus

+0

@octopusgrabbus: Chức năng 'max' là gì? –

+0

Tìm thấy phần liên quan trong sách hướng dẫn GCC, nhưng tôi vẫn không biết nếu điều này được chuẩn hóa hay chỉ là một quy ước không chính thức – mensi

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