2009-03-10 34 views
5

Tôi tò mò muốn biết tại sao các trường bit có cùng kiểu dữ liệu có kích thước nhỏ hơn so với các loại dữ liệu hỗn hợp .tại sao các trường bit cho cùng một kiểu dữ liệu có kích thước nhỏ hơn so với trường bit cho kiểu dữ liệu hỗn hợp

struct xyz 
{ 
    int x : 1; 
    int y : 1; 
    int z : 1; 
}; 


struct abc 
{ 
    char x : 1; 
    int y : 1; 
    bool z : 1; 
}; 

sizeof (xyz) = 4 sizeof (abc) = 12.

Tôi đang sử dụng VS 2005, máy 64bit x86.

Câu trả lời cấp máy/trình biên dịch bit sẽ rất tuyệt.

Trả lời

4

Căn chỉnh.

Trình biên dịch của bạn sẽ sắp xếp các biến theo cách có ý nghĩa đối với kiến ​​trúc của bạn. Trong trường hợp của bạn, char, intbool là các kích thước khác nhau, vì vậy nó sẽ đi theo thông tin đó thay vì gợi ý trường bit của bạn.

Đã có một số thảo luận trong số this question về vấn đề này.

Giải pháp là cung cấp cho #pragma chỉ thị hoặc __attributes__ để trình biên dịch của bạn hướng dẫn nó bỏ qua tối ưu hóa căn chỉnh.

+1

Lưu ý rằng các trường bit không thực sự có yêu cầu căn chỉnh. –

+0

Không, nhưng trình biên dịch không có nghĩa vụ đóng gói chúng. – greyfade

+0

Xem ISO14882: 2003, §9.6, đoạn 1. – greyfade

3

Các tiêu chuẩn C (phiên bản 1999, §6.7.2.1, trang 102, điểm 10) nói điều này:

An thực hiện có thể phân bổ bất kỳ đơn vị lưu trữ địa chỉ đủ lớn để giữ một chút trường . Nếu đủ không gian còn lại, một trường bit ngay lập tức sau một trường bit khác trong một cấu trúc sẽ được đóng gói thành các bit liền kề của cùng một đơn vị.

Dường như không có bất kỳ từ ngữ nào để cho phép đóng gói bị ảnh hưởng bởi các loại trường. Vì vậy, tôi sẽ kết luận rằng đây là một lỗi trình biên dịch.

gcc tạo cấu trúc 4 byte trong cả hai trường hợp, trên cả máy 32 bit và 64 bit, trong Linux. Tôi không có VS và không thể kiểm tra điều đó.

+1

C++ 03, §9.6, đoạn 1 cho biết, "Phân bổ các trường bit trong một đối tượng lớp được thực hiện xác định. Căn chỉnh các trường bit được thực hiện xác định. Các trường bit được đóng gói vào một số đơn vị phân bổ địa chỉ." Có vẻ như mahesh đang sử dụng trình biên dịch C++. – greyfade

+0

Mặt khác, ông cũng gắn thẻ này như một câu hỏi C, không chỉ là C++. Tôi đoán câu trả lời là khác nhau cho C và C++. –

+0

Tôi sẽ cảnh giác khi tuyên bố đây là "lỗi" vì bạn đã trích dẫn từ tiêu chuẩn ISO C99. MSVC++ không yêu cầu tuân thủ C99. Nó hỗ trợ chuẩn ISO C90/ANSI C89. – Clifford

0

Đó là lỗi của trình duyệt hoặc một số lỗi mã. Tất cả các bit được gán trong cấu trúc luôn cố gắng làm cho kích thước của kiểu dữ liệu cao nhất được xác định. ví dụ: Trong struct xyz sizeof kiểu dữ liệu cao nhất là 4 tức là int. Trong thời trang tương tự cho cấu trúc thứ hai abc kích thước loại dữ liệu cao nhất là 4 cho int.

Trường hợp như thể chúng tôi thay đổi các biến cấu trúc như sau: struct abc { char a: 1; char b: 1; bool c: 1; };

sizeof (abc) sẽ là 1 không 4. Vì kích thước loại dữ liệu cao nhất là 1 và tất cả các bit đều phù hợp với 1byte char.

kiểm tra khác nhau có thể được thực hiện bằng cách thay đổi kiểu dữ liệu trong cấu trúc.

liên kết cho đầu ra dựa trên cấu trúc cũ: Visit http://codepad.org/6j5z2CEX

liên kết cho đầu ra dựa trên cấu trúc trên được xác định bởi tôi: Visit http://codepad.org/fqF9Ob8W

Để tránh vấn đề như vậy cho các cấu trúc sizeof chúng ta sẽ đóng gói đúng cấu trúc sử dụng #pragma pack macro.

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