2012-06-20 25 views
6
// <windef.h> 

typedef int     BOOL; 

Đây không phải là lãng phí bộ nhớ vì int là 32 bit?Tại sao WinAPI sử dụng int (32 bit) cho loại BOOL?

Chỉ trong trường hợp tôi đã sai, tôi đã thử gửi một thông thường bool* đến một chức năng yêu cầu BOOL* và không hoạt động cho đến khi tôi sử dụng typedef int.

+5

Ngày xửa ngày xưa, 'bool' không có loại C. Xem http://stackoverflow.com/questions/1608318/is-bool-a-native-c-type – dyp

+1

oman Tôi rất dum Tôi thực sự dum cho thực – y2k

+0

Tôi biết rằng Bool bool đã được thêm vào C do đó, những gì là HOLDUP TẠI ĐÂY – y2k

Trả lời

17

Chà, hãy chậm lại một chút ở đó. Trước hết, tôi chắc rằng các lập trình viên đã sử dụng các biến boolean 4 byte int cho các biến boolean kể từ khi bắt đầu lập trình trên x86. (Có sử dụng để không có những thứ như một kiểu dữ liệu bool). Và tôi muốn mạo hiểm để đoán rằng typedef này là trong Windows 3.1 <Windows.h>.

Thứ hai, bạn cần hiểu thêm một chút về kiến ​​trúc. Bạn có một máy 32-bit, có nghĩa là tất cả các thanh ghi CPU có độ rộng 4 byte hoặc 32 bit. Vì vậy, đối với hầu hết các truy cập bộ nhớ, nó là hiệu quả hơn để lưu trữ và truy cập các giá trị 4 byte so với giá trị 1 byte.

Nếu bạn có bốn biến boolean 1 byte được đóng gói thành một đoạn bộ nhớ 4 byte, ba trong số đó không phải là liên kết DWORD (4 byte). Điều này có nghĩa là bộ điều khiển CPU/bộ nhớ thực sự phải thực hiện thêm nhiều hơn để nhận giá trị.

Và trước khi bạn đi đập vào MS để tạo kiểu chữ "lãng phí" đó. Hãy xem xét điều này: Dưới mui xe, hầu hết các trình biên dịch (probabily) vẫn triển khai kiểu dữ liệu bool làm 4 byte int vì cùng một lý do mà tôi vừa đề cập. Hãy thử nó trong gcc, và hãy xem tập tin bản đồ. Tôi cá là tôi đúng.

+1

Điều này, các vấn đề liên kết với 1 byte là khủng khiếp với một đăng ký kích thước tiêu chuẩn. – TheZ

+3

Trên x86, tuy nhiên, nó dễ dàng nhận được 1 byte vì nó là 4. Các vấn đề căn chỉnh sẽ được phát khi bạn có các giá trị nhiều byte. Sự thiếu hiệu quả lớn là bạn đang đọc 4 byte khi 1 sẽ làm ... nhưng cả hai cách phải mất cùng một lượng thời gian. – cHao

+2

Đối số lịch sử là hợp lệ, phần còn lại thì không. GCC tạo ra một bool 1 byte. Tải/lưu trữ 1 byte chắc chắn là khác nhau ở cấp chip và có ý nghĩa khác nhau cho bộ nhớ đệm, liên kết, và đồng thời hơn tải 4 byte. –

2

Bộ vi xử lý là 32 bit và có cờ đặc biệt khi nó hoạt động trên số nguyên không, giúp kiểm tra các giá trị boolean 32 bit rất, rất, rất nhanh.

Kiểm tra giá trị boolean 1 bit hoặc một byte sẽ chậm hơn nhiều lần.

Nếu bạn lo lắng về không gian bộ nhớ, bạn có thể lo lắng về 4 biến bool byte.

Hầu hết các lập trình viên, tuy nhiên, lo lắng nhiều hơn về hiệu suất và do đó, mặc định là sử dụng bool 32 bit nhanh hơn.

Bạn có thể làm cho trình biên dịch của mình tối ưu hóa để sử dụng bộ nhớ nếu điều này làm phiền bạn.

+1

@cHao có, nhưng bạn phải làm nhiều việc hơn để nhận byte đó từ bộ nhớ. Bạn cần phải kéo ít nhất 32 bit và mặt nạ nó. –

+2

Hơn nữa, hầu hết các CPU x86 những ngày này - 32 bit CPU! - Có xe buýt dữ liệu 64 bit (Intel đã thực hiện nó kể từ P6, tôi tin rằng ... có lẽ ngay cả Pentium gốc), vì vậy việc che và/hoặc dịch chuyển sẽ * vẫn * cần thực hiện. – cHao

13

Thứ nhất, loại được sử dụng trong API hệ thống phải độc lập với ngôn ngữ càng tốt, vì API đó sẽ được sử dụng bởi vô số ngôn ngữ lập trình. Vì lý do này, bất kỳ loại "khái niệm" nào có thể không tồn tại ở một số ngôn ngữ hoặc có thể được thực hiện khác nhau ở các ngôn ngữ khác đều không được đề cập đến. Ví dụ: bool phù hợp với danh mục đó. Trên hết, trong một API hệ thống, bạn nên giữ số lượng kiểu giao diện ở mức tối thiểu. Bất cứ điều gì có thể được đại diện bởi int phải được đại diện bởi int.

Thứ hai, xác nhận của bạn về điều này là "lãng phí bộ nhớ" không có ý nghĩa gì. Để trở thành "một sự lãng phí bộ nhớ", người ta sẽ phải xây dựng một loại dữ liệu tổng hợp liên quan đến một số lượng lớn các yếu tố BOOL. Windows API không sử dụng các loại dữ liệu như vậy. Nếu bạn xây dựng loại dữ liệu lãng phí như vậy trong chương trình của bạn, nó thực sự là lỗi của bạn. Trong khi đó, Windows API không theo bất kỳ cách nào buộc bạn lưu trữ các giá trị boolean của bạn theo loại BOOL. Bạn có thể sử dụng byte và thậm chí bit cho mục đích đó.Nói cách khác, BOOL là giao diện hoàn toàn . Đối tượng của BOOL loại thường không chiếm bất kỳ bộ nhớ dài hạn nào cả, nếu bạn đang sử dụng nó một cách chính xác.

+3

@DyP: Không thực sự. AFAIK có các ngôn ngữ hiện tại không hỗ trợ 1 loại byte đơn giản vì chúng không có lý do gì. – AnT

+2

@AndreyT Chỉ cần nghĩ về tất cả các kiểu dữ liệu BF không hỗ trợ ... –

+0

Tôi vẫn thực sự thích cách bạn giải thích điều này. Chúng tôi đang xử lý ** API **, chứ không phải cấu trúc dữ liệu. –

2

Trước đây BOOL được sử dụng làm mọi thứ không phải là 0 = loại TRUE. Ví dụ, một thủ tục hộp thoại trả về một BOOL, có thể mang nhiều thông tin. Chữ ký dưới đây là từ Microsoft's own documentation:

BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) 

Kết quả chữ ký và chức năng lồng việc một số vấn đề, vì vậy in the modern API nó thay vì

INT_PTR CALLBACK DialogProc(
    _In_ HWND hwndDlg, 
    _In_ UINT uMsg, 
    _In_ WPARAM wParam, 
    _In_ LPARAM lParam 
); 

khai mới lạ này có duy trì tương thích với cái cũ. Điều này có nghĩa là INT_PTRBOOL phải có cùng kích thước. Điều đó có nghĩa là trong lập trình 32 bit, BOOL là 32 bit.

Nói chung, kể từ BOOL có thể là bất kỳ giá trị nào, không chỉ 0 và 1, đó là ý tưởng rất không tốt để so sánh BOOL với TRUE. Và mặc dù nó hoạt động để so sánh nó với FALSE, đó cũng thường là thực hành không tốt vì nó có thể dễ dàng cho mọi người ấn tượng rằng so sánh với TRUE sẽ là OK. Ngoài ra, bởi vì nó khá không cần thiết.

Nhân tiện, có nhiều loại boolean trong API Windows, cụ thể là VARIANT_BOOL là 16 bit và trong đó TRUE hợp lý được biểu diễn dưới dạng bitmap tất cả 1, tức là -1 dưới dạng giá trị đã ký & hellip;

Đó là lý do bổ sung tại sao không nên so sánh trực tiếp với FALSE hợp lý hoặc TRUE.

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