2009-03-11 37 views
14

Tôi đã xem qua một số C mã nơi tác giả sử dụng các thành ngữ sau khắp nơi:Điểm của câu nói "#define FOO FOO" trong C là gì?

typedef __int32 FOO_INT32; 
#define FOO_INT32 FOO_INT32 

điểm để làm điều này là gì? Không phải là typedef là đủ? Đó là giải pháp cho một số trình biên dịch số C có sẵn không?

+0

cảm thấy tự do để đánh dấu câu hỏi này như đã trả lời;) – claf

Trả lời

28

Với sự hướng dẫn #define, sau đó bạn sẽ có thể kiểm tra nếu typedef đã được thực hiện ở một nơi khác trong mã sử dụng:

#ifdef FOO_INT32 
FOO_INT32 myfoo; 
#else 
int myfoo; 
#endif 
2

Đó là một thực tế đó là đôi khi thực hiện trong tiêu đề. #define cho phép kiểm tra thời gian biên dịch sự tồn tại của typedef. Điều này cho phép mã như:

#ifdef FOO_INT32 
FOO_INT32 myfoo; 
#else 
int myfoo; 
#endif 

hoặc làm bảo vệ đúng #define, tương tự như bảo vệ tệp tiêu đề.

#ifndef FOO_INT32 
typedef int FOO_INT32 
#define FOO_INT32 FOO_INT32 
#endif 

Nó không nhất thiết là một thói quen tốt, nhưng nó có công dụng của nó, đặc biệt là khi bạn có một số tiêu đề mà sử dụng các loại được xác định bởi các thư viện khác, nhưng bạn muốn cung cấp sản phẩm thay thế của riêng bạn đối với trường hợp khi bạn không sử dụng những thư viện đó.

+0

cùng câu trả lời là người đầu tiên ... – user65636

+0

Tôi đoán nếu có #ifndef FOO_INT32 ngay trước typedef, ông sẽ phải đoán việc sử dụng như bảo vệ. – user65636

+1

Nó hoàn toàn không phải là thực hành tốt cho mã mới. –

1

Mẫu này cũng hữu ích cho việc phát hiện tính năng của thanh ghi trong bộ vi xử lý, như trong this question. Ví dụ, có thể có hai tập tin tương tự như tiêu đề, một trong số đó định nghĩa một bộ đếm thời gian, và một trong đó định nghĩa 2:

cheapprocessor.h:

#define TMR1 TMR1 
extern volatile int TMR1; 

expensiveprocessor.h:

#define TMR1 TMR1 
extern volatile int TMR1; 
#define TMR2 TMR2 
extern volatile int TMR2; 

Có nghĩa là trong bạn mã chính, khi bạn bao gồm một số chung là processor.h đại diện cho tiêu đề thích hợp cho mục tiêu, bạn có thể phát hiện các tính năng:

#include <processor.h> 

#ifdef TMR2 
    x = TMR2; 
#else 
    x = 0; // no timer, probably because we're on the cheaper model 
#endif 
1

Một lý do khác là tiêu chuẩn có thể yêu cầu định nghĩa là macro.

Snippet từ glibc netinet/in.h:

/* Standard well-defined IP protocols. */ 
enum 
    { 
    IPPROTO_IP = 0, /* Dummy protocol for TCP. */ 
#define IPPROTO_IP  IPPROTO_IP 
    IPPROTO_ICMP = 1,  /* Internet Control Message Protocol. */ 
#define IPPROTO_ICMP  IPPROTO_ICMP 
    IPPROTO_IGMP = 2,  /* Internet Group Management Protocol. */ 
#define IPPROTO_IGMP  IPPROTO_IGMP 

đây những biểu tượng enum cũng được xuất khẩu như các macro theo yêu cầu của the relevant POSIX spec, trích dẫn:

Tiêu đề phải xác định các macro sau để sử dụng như giá trị của đối số cấp của getockopt() và setsockopt():

IPPROTO_IP

Internet protocol. 

IPPROTO_IPV6

Internet Protocol Version 6. 

...

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