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

typedef int     BOOL; 

Разве это не пустая трата памяти, так как int 32 бит?Почему WinAPI использует int (32 бит) для типа BOOL?

На всякий случай я ошибся, я попробовал отправить нормальный bool* на функцию, которая требовала BOOL* и не работала, пока я не использовал typedef int.

+5

некогда, 'bool' не было типа C. См. Http://stackoverflow.com/questions/1608318/is-bool-a-native-c-type – dyp

+1

oman Я такой dum Я настоящий dum для реального – y2k

+0

Я знал, что НО Bool был добавлен в C, так что это HOLDUP ЗДЕСЬ – y2k

ответ

17

Ничего себе, замедлитесь там немного. Прежде всего, я уверен, что программисты использовали 4 байта int s для булевых переменных с начала программирования на x86. (Там не было такой вещи, как тип данных bool). И я рискну предположить, что этот же typedef находится в Windows 3.1 <Windows.h>.

Во-вторых, вам нужно понять немного больше об архитектуре. У вас 32-разрядная машина, что означает, что все регистры процессора имеют ширину 4 байта или 32 бита. Поэтому для большинства обращений к памяти это более эффективно для хранения и доступа к 4-байтовым значениям, чем для 1-байтового значения.

Если у вас есть четыре 1-байтовые булевы переменные, упакованные в один 4-байтовый блок памяти, три из них не соответствуют DWORD (4 байтам). Это означает, что контроллер CPU/памяти на самом деле должен делать больше работать, чтобы получить значение.

И прежде, чем вы начнете разбить MS, чтобы сделать этот «расточительный» typedef. Рассмотрим это: под капотом большинство компиляторов (probabily) все еще реализуют тип данных bool как 4-байтовый int по тем же причинам, о которых я только что упомянул. Попробуйте в gcc и посмотрите файл карты. Держу пари, что я прав.

+1

Это, проблемы с выравниванием с 1 байтом, ужасно со стандартным регистром размера. – TheZ

+3

На x86, тем не менее, так же легко получить 1 байт, как и 4. Задачи выравнивания вступают в игру, когда у вас есть многобайтовые значения. Основная неэффективность заключается в том, что вы читаете 4 байта, когда 1 будет делать ... но в любом случае это занимает столько же времени. – cHao

+2

Исторический аргумент действителен, остальное - нет. GCC создает 1-байтовый bool. Загрузка/сохранение 1 байта определенно отличается на уровне чипа и имеет разные последствия для кеширования, выравнивания и параллелизма, чем загрузка 4 байтов. –

2

Процессор 32 бит и имеет специальный флаг, когда он работает с нулевым целым числом, делая тестирование для 32-битных булевых значений очень, очень и очень быстро.

Тестирование для 1 бита или одного байтового логического значения будет во много раз медленнее.

Если вас беспокоит пространство памяти, вы можете беспокоиться о 4 байтовых переменных bool.

Большинство программистов, однако, больше обеспокоены производительностью, и поэтому по умолчанию используется более быстрый 32-битный bool.

Возможно, вы сможете оптимизировать свой компилятор для использования памяти, если это вас беспокоит.

+1

@cHao да, но вам нужно больше работать, получая этот байт из памяти. Вам нужно потянуть как минимум 32 бита и замаскировать его. –

+2

К тому же большинство процессоров x86 в наши дни - 32-битные! - имеют 64-битные шины данных (Intel сделала это с P6, я считаю ... может быть, даже оригинальный Pentium), так что маскировка и/или переключение будут * еще нужны. – cHao

13

Во-первых, тип, используемый в API системы, должен быть как можно более независимым от языка, поскольку этот API будет использоваться множеством языков программирования. По этой причине любые «концептуальные» типы, которые могут либо не существовать на некоторых языках, либо могут быть реализованы по-разному на других языках, не могут быть и речи. Например, bool подходит для этой категории. Кроме того, в системном API очень полезно сохранить минимальное количество типов интерфейсов. Все, что может быть представлено int, должно быть представлено int.

Во-вторых, ваше утверждение об этом как о «пустой трате памяти» не имеет никакого смысла. Чтобы стать «пустой тратой памяти», нужно было бы создать совокупный тип данных, который включает в себя чрезвычайно большое количество элементов BOOL. В Windows API таких типов данных нет. Если вы создали такой расточительный тип данных в своей программе, это на самом деле ваша ошибка. Между тем, Windows API никоим образом не заставляет вас хранить ваши логические значения в BOOL типа. Для этой цели вы можете использовать байты и четные биты.Другими словами, BOOL представляет собой чисто интерфейс. Объект типа BOOL обычно не занимает никакой долгосрочной памяти, если вы используете его правильно.

+3

@ DyP: Не совсем. AFAIK существуют существующие языки, которые вообще не поддерживают 1 байтовый тип просто потому, что у них нет причин. – AnT

+2

@AndreyT Подумайте о всех типах данных, которые BF не поддерживает ... –

+0

Мне все еще очень нравится, как вы это объяснили. Мы имеем дело с ** API **, а не с структурой данных. –

2

Исторически BOOL использовался как ничего-не-0 = ИСТИННЫЙ тип. Например, процедура диалога вернула BOOL, которая могла содержать много информации. Подпись ниже от Microsoft's own documentation:

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

результат подписи и функции сплавлены несколько вопросов, так in the modern API это вместо

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

Эта новомодная декларация должна оставаться совместимой со старым. Это означает, что INT_PTR и BOOL должны быть одинакового размера. Это означает, что в 32-битном программировании BOOL - 32 бита.

В целом, поскольку BOOL может быть любым значением, а не только 0 и 1, это очень непростая идея сравнить BOOL с TRUE. И хотя это работает, чтобы сравнить его с FALSE, это, как правило, и плохая практика, потому что это может легко дать людям впечатление, что по сравнению с TRUE все будет в порядке. Кроме того, потому что это совершенно необязательно.

Кстати, есть еще булевы типы в API Windows, в частности VARIANT_BOOL, которая составляет 16 бит и где логическое значение TRUE представлено в виде всего 1 bitpattern, т.е. -1 как знаковое значение & hellip;

Это дополнительная причина, по которой нецелесообразно сравнивать напрямую с логическим FALSE или TRUE.

Смежные вопросы