2013-07-29 34 views
5

Trong thư viện FreeImagePlus, trong FreeImage.h, có một hài hước #define mà dường như để tạo ra một typedef và một enum có cùng tên:Typedef và enum có cùng tên?

#define FI_ENUM(x)  typedef int x; enum x 

này được mở rộng bằng vi xử lý mã như:

typedef int FREE_IMAGE_FILTER; 
enum FREE_IMAGE_FILTER { 
FILTER_BOX = 0, 
FILTER_BICUBIC = 1, 
[...] 

Điều này làm gì? Thậm chí có hợp pháp để có một số typedefenum có cùng tên không? Tuy nhiên, không phải là enum tương thích với int? Tại sao FreeImage làm điều này?

Trả lời

6

Tên của cấu trúc, đoàn thể và liệt kê sống trong không gian tên riêng của chúng. Đó là lý do tại sao bạn có thể khai báo biến số struct/union/enum có cùng tên với số thực tế struct/union/enum.

Và nó không phải là tên của hoàn enum (ví dụ cho enum X Tôi có nghĩa là X) mà đã tương thích với một số nguyên, đó là tên bên kiểu liệt kê.

+0

Cảm ơn, không biết về các không gian tên. Tuy nhiên, "typedef int" giúp đỡ ở đâu? Có mã nào bị vỡ mà không có nó? – sleske

+0

@ sleske Nói chung nó không cần thiết, bạn cũng có thể làm 'typedef enum X {...} X;' Trừ khi có các phép toán trên các biến kiểu 'X' không thể thực hiện được trên các kiểu liệt kê. –

0

Trích dẫn C99 N1256 draft 6.2.1 "Lĩnh vực nhận diện":

Một định danh có thể biểu thị một đối tượng; một hàm; một thẻ hoặc một thành viên của một cấu trúc, công đoàn, hoặc điều tra; một tên typedef; tên nhãn; tên macro; hoặc tham số macro.

điều đó có nghĩa rằng trong:

typedef int id; 

id là một định danh.

Và từ 6.2.3 "không gian Tên của định danh":

BEGIN QUOTE

Nếu có nhiều hơn một lời tuyên bố của một định danh cụ thể là có thể nhìn thấy ở bất kỳ điểm nào trong một đơn vị dịch thuật, bối cảnh cú pháp disambiguates sử dụng đề cập đến các thực thể khác nhau. Do đó, có các không gian tên riêng biệt cho các danh mục định danh khác nhau, như sau:

  • tên nhãn (bị định hướng bởi cú pháp khai báo và sử dụng nhãn);
  • các thẻ của cấu trúc, công đoàn và liệt kê (được định hướng bằng cách theo dõi bất kỳ từ khóa nào trong cấu trúc, công đoàn hoặc enum);
  • thành viên của cấu trúc hoặc công đoàn; mỗi cấu trúc hoặc công đoàn có một không gian tên riêng cho các thành viên của nó (được định hướng bởi loại biểu thức được sử dụng để truy cập thành viên thông qua toán tử. hoặc ->);
  • tất cả các số nhận dạng khác, được gọi là số nhận dạng thông thường (được khai báo trong người khai báo thông thường hoặc dưới dạng hằng số liệt kê).

END QUOTE

Vì vậy, trong:

typedef int id; 
enum id {ID0}; 
  • các id đầu tiên là một định danh thông thường
  • thứ hai là một định danh thẻ

một cả hai có thể cùng tồn tại bình yên.

Mặt khác, chúng ta không thể làm điều gì đó như:

typedef int id; 
int id; 

vì cả hai sẽ là bộ nhận diện thông thường.

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