2017-06-19 14 views
9

Một vĩ mô cổ điển để tính số phần tử trong một mảng là thế này:Có cách nào để countof() kiểm tra nếu đối số của nó là một mảng không?

#define countof(a) (sizeof(a)/sizeof(*(a))) 

Vấn đề ở đây là nó không âm thầm nếu đối số là một con trỏ thay vì một mảng. Có một cách di động để đảm bảo vĩ mô này chỉ được sử dụng với một mảng thực tế?

+1

Biên dịch xác nhận rằng sizeof (& table [0])! = Sizeof (bảng [0]) và bạn sẽ ở đó trong hầu hết các trường hợp, chắc chắn khi các cấu trúc nhiều thành viên tham gia. Kích thước của một con trỏ cũng là sizeof của một con trỏ tới một con trỏ. Đối với các cấu trúc, điều này chỉ có thể đúng đối với một cấu trúc rất đơn giản. Không hoàn hảo, nhưng khá gần với mục tiêu của bạn trong hầu hết các trường hợp. Và di động. –

+0

@ B.Nadolson Trong khi nó có thể làm việc cho một số trường hợp cụ thể, tôi có lẽ sẽ đặt rất nhiều ý kiến ​​xung quanh nơi bạn sử dụng nó (theo nguyên tắc ít ngạc nhiên nhất). Có nhiều trường hợp kiểm tra đó không hoạt động chính xác nhưng một lập trình viên có thể giả định nó. – tangrs

+1

Bảng thuộc tính '(intptr_t) & table == (intptr_t) 'hợp lệ cho một mảng, trong trường hợp con trỏ nó chỉ giữ nếu nó trỏ đến chính nó, điều này hiếm khi xảy ra. – Marian

Trả lời

4

Sử dụng một hàm built-in không cầm tay, đây là một vĩ mô để thực hiện một sự khẳng định tĩnh a là một mảng:

#define assert_array(a) \ 
    (sizeof(char[1 - 2 * __builtin_types_compatible_p(typeof(a), typeof(&(a)[0]))]) - 1) 

Nó hoạt động với cả hai gccclang. Tôi sử dụng nó để làm cho countof() vĩ mô an toàn hơn:

#define countof(a) (sizeof(a)/sizeof(*(a)) + assert_array(a)) 

Nhưng tôi không có một giải pháp di động cho vấn đề này.

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