2012-12-07 11 views
5

Tôi cần phân bổ một mảng theo số lượng phần tử enum có. Tôi đã làm như sau:Thành viên enum có thể là kích thước của một mảng trong ANSI-C không?

enum { A, B, C, LAST }; 
char buf[LAST]; 

Điều đó làm việc tốt, ngay cả với cờ -ansi -pedantic. Nhưng tôi không chắc chắn nếu nó là một GCC hoặc clang (hỗ trợ hầu hết, nếu không phải tất cả các phần mở rộng GCC) phần mở rộng hoặc thực sự cho phép bởi tiêu chuẩn ANSI C và sẽ hoạt động tốt trong bất kỳ trình biên dịch C với ANSI-C std. Ai đó có thể làm rõ nó?

Trả lời

6

Cả hai tiêu chuẩn C89 (mục 3.5.2.2) và C99 (phần 6.7.2.2) đều xác định e enums theo cùng một cách: ERS Speci fi

6.7.2.2 Enumeration (Khoản 3), http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

3.5.2.2 specifiers Enumeration (Khoản 3), http://flash-gordon.me.uk/ansi.c.txt

Cả đọc :

[...] Một điều tra viên với = de fi nes hằng số liệt kê của nó là giá trị của biểu thức hằng số.Nếu điều kiện đầu tiên không có =, giá trị của hằng số liệt kê là 0. Mỗi điều tra tiếp theo không có hằng số liệt kê là giá trị của biểu thức hằng số thu được bằng cách thêm 1 vào giá trị của hằng số liệt kê trước đó. [...]

Do đó, theo cú pháp của bạn, bất kỳ trình biên dịch tuân thủ chuẩn nào cũng sẽ chạy mã của bạn một cách chính xác.

2

đó làm việc tốt, ngay cả với cờ -pedantic -ansi

Vì vậy, nó không phải là một phần mở rộng GNU. Có, điều này là tốt trong ANSI C, bởi vì các thành viên của một enum là các biểu thức không đổi.

+0

Điều này cho rằng GCC tuân theo tiêu chuẩn 100% :-) –

1

Từ C Standard, đoạn 6.2.5 (loại):

16 Một liệt kê bao gồm một tập hợp các tên giá trị số nguyên không đổi. Mỗi liệt kê riêng biệt cấu thành một loại liệt kê khác nhau.

17 Loại char, các loại số nguyên đã ký và không dấu và các loại được liệt kê được gọi chung là các loại số nguyên.

Ngoài ra, đoạn 6.7.2.2 (specifiers Enumeration):

Biểu thức xác định giá trị của một hằng liệt kê sẽ là một biểu thức hằng số nguyên mà có một biểu diễn giá trị như một int .

2

Ai đó có thể làm rõ điều này?

tôi chắc chắn rằng bạn đã biết, một enum chỉ là appling một nhãn cho một số:

enum 
{ A, // 0 
    B, // 1 
    C, // 2 
    LAST // 3 
}; 

Vì vậy, thực sự:

char buf[LAST]; 

là không khác gì hơn:

char buf[3]; 
2

Như những người khác đã nói, nó hợp lệ. Nhưng tôi nghĩ không có ai trích dẫn các phần phù hợp cho đến nay. Những người có liên quan từ N1256 C99 draft là: 6,6 "biểu thức hằng số" đoạn 6:

Một số nguyên liên tục expression99) có kiểu số nguyên và chỉ có toán hạng đó là hằng số nguyên, liệt kê hằng [...]

và sau đó 6.7.5.2 "mảng declarators" đoạn 4:

Nếu kích thước là một biểu thức hằng số nguyên và các loại nguyên tố có một kích thước không đổi được biết, loại mảng không phải là một loại mảng chiều dài thay đổi [...]

Vì vậy, về cơ bản:

  • hằng liệt kê là những biểu hiện thường xuyên
  • cho mảng không phải là chiều dài thay đổi, chúng ta cần một biểu thức hằng

Tôi tin rằng 6.7.2.2 " Các thông số liệt kê "mà những người khác đã trích dẫn các cuộc đàm phán về tuyên bố số enum, không sử dụng các điều tra viên. Tất nhiên, vì khi khai báo chúng, bạn cần hằng số thời gian biên dịch, chúng tôi hy vọng rằng chúng cũng cần phải biên dịch hằng số thời gian khi được sử dụng trong các biểu thức.

+1

Cảm ơn bạn. Bạn đúng về câu trả lời trước đó không trích dẫn các phần phù hợp từ tiêu chuẩn. Khái niệm then chốt là chứng minh rằng giá trị enum và kích thước của một mảng tại thời điểm khai báo chính xác là cùng một loại giá trị. – cesss

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