2010-07-23 32 views
21

sizeof() không hoạt động khi áp dụng cho bitfields:Có bit tương đương với sizeof() trong C không?

# cat p.c 
    #include<stdio.h> 
    int main(int argc, char **argv) 
    { 
    struct { unsigned int bitfield : 3; } s; 
    fprintf(stdout, "size=%d\n", sizeof(s.bitfield)); 
    } 
# gcc p.c -o p 
    p.c: In function ‘main’: 
    p.c:5: error: ‘sizeof’ applied to a bit-field 

... rõ ràng, vì nó không thể trở về một điểm kích thước hoặc một cái gì đó một phần nổi. Tuy nhiên, nó đưa ra một câu hỏi thú vị. Có phải có tương đương, trong C, sẽ cho bạn biết số bit trong một biến/loại không? Lý tưởng nhất, nó cũng sẽ hoạt động với các loại thông thường, như charint, ngoài các bitfield.

Cập nhật:

Nếu không có tương đương với ngôn ngữ của sizeof() cho bitfields, cách hiệu quả nhất tính nó là gì - trong thời gian chạy! Hãy tưởng tượng bạn có các vòng phụ thuộc vào điều này, và bạn không muốn chúng phá vỡ nếu bạn thay đổi kích thước của bitfield - và không gian lận công bằng và làm cho kích thước bitfield và chiều dài vòng lặp là một macro. ;-)

Trả lời

16

Bạn không thể xác định kích thước của trường bit trong C. Tuy nhiên, bạn có thể tìm kích thước bằng các bit khác bằng cách sử dụng giá trị CHAR_BIT, được tìm thấy trong giới hạn.h. Kích thước theo bit chỉ đơn giản là CHAR_BIT * sizeof (loại).

Đừng cho rằng một byte C là một octet, nó là ít nhất 8 bit. Có máy thực tế với 16 hoặc thậm chí 32 bit byte.

Về sửa đổi của bạn: Tôi có thể nói một chút trường int a: n; có kích thước n bit theo định nghĩa. Các bit đệm bổ sung khi đặt trong một cấu trúc thuộc về cấu trúc chứ không phải vào trường bit.

Lời khuyên của tôi: Không sử dụng các trường bit nhưng sử dụng (mảng) unsigned char và hoạt động với bitmask. Bằng cách đó, rất nhiều hành vi (tràn, không đệm) được xác định rõ.

+0

+1 tuyệt vời, không biết về CHAR_BIT. nếu bạn cần tính toán kích thước bitfield khi chạy? – eruciform

+0

Điều đó là không thể (một trong những lý do tại sao mọi người tránh các trường bit). Một trình biên dịch có thể thực hiện điều này như là một phần mở rộng cho điều này, nhưng tôi chưa bao giờ nghe nói về một. – schot

+0

@schot: byte! = Char. Trong C, char luôn luôn là 8 bit, do đó 'CHAR_BIT' luôn luôn là 8. Bất kể CPU/etc. Thời gian dài trước đây nó có thể đã khác nhau (liên tục tồn tại vì những lý do lịch sử) nhưng không còn nữa. Kiểm tra C99, 'limits.h'. – Dummy00001

2

Không thể tìm thấy kích thước của trường bit sử dụng sizeof(). Tham khảo C99:

  • 6.5.3.4 The sizeof operator, bit lĩnh vực rõ ràng là không được hỗ trợ bởi sizeof()
  • 6.7.2.1 Structure and union specifiers đây nó được làm rõ rằng bit trường không tự đứng thành viên.

Nếu không, bạn có thể thử chỉ định cho thành viên bit trường -1u (giá trị với tất cả các bit được đặt) và sau đó tìm chỉ mục của bit quan trọng nhất. Ví dụ. (chưa được kiểm tra):

s.bitfield = -1u; 
num_bits = ffs(s.bitfield+1)-1; 

man ffs để biết thêm.

+0

+1 điều này đang nhìn gần hơn với một công cụ tìm chiều dài tối ưu. 'ffs()' là gì? – eruciform

+1

@eruciform: ffs = tìm tập đầu tiên. một hàm (thường được ánh xạ trực tiếp đến một lệnh CPU) để tìm bit đầu tiên được đặt trong int. bit được đánh số từ 1. nếu int đầu vào là 0, thì trả về là quá 0. – Dummy00001

+0

tốt đẹp! đó chắc chắn là một chức năng mà tôi chưa từng thấy. và ở đây tôi nghĩ rằng tôi đã phần lớn đã ghé thăm các góc được bọc bởi mạng nhện của C qua nhiều năm! – eruciform

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