(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

BOOL или BOOLEAN - вот в чем вопрос?

Источник: habrahabr
habrahabr

Я как-то никогда не задумывался над тем, что лучше использовать BOOL или BOOLEAN? Конечно же, BOOL - это и короче и во всех учебниках по Windows встречается именно BOOL. Как бы не так! Буквально вчера я битый час занимался поиском ошибки там, где ее не должно было быть.

Оказалось, что единственно истинный тип, впрямую связанный с типом bool, который определен стандартами языка С++, это именно BOOLEAN. А BOOL это не что иное, как "typedef int BOOL;" и находится в windows.h (точнее в WinDef.h, но это неважно)

Рассмотрим подробнее исходный код функции, сравнивающий два числа:

#include <stdio.h>
#include <windows.h>

bool CompareInt(int i1, int i2)
{
    if (i1==i2)
        return true; //UPD1: было TRUE
    else
        return false; //UPD1: было FALSE
}

typedef BOOL (*CallBack)(int, int);

void main(void)
{
    CallBack IsEqual = (CallBack)CompareInt;

    if ( !IsEqual(0x1234, 0x5678) )
        printf("Not equals");
    else
        printf("Equals");
}

После компилирования Visual Studio и запуска, имеем: Equals

Тогда поменяем BOOL на BOOLEAN:

typedef BOOLEAN (*CallBack)(int, int);

Компилируем, запускаем, получаем: Not equals (что и должно было получиться с самого начала)

Вывод: никогда не пользуйтесь BOOL, только BOOLEAN.

UPD1: Поправил в возврате функции, было TRUE/FALSE стало true/false для чистоты эксперимента.

UPD2: Раскрываю "черную магию". Возврат bool идет в типе char (регистр CPU al), так как bool в Visual Studio приравнен к char (и BOOLEAN там тоже приравнен к char поэтому замена BOOL на BOOLEAN убирает ошибку).

А вот тип BOOL приравнен к int (регистр eax), поэтому, когда функция возвращает false (он же FALSE), то при этом в нуль устанавливается только младший байт al, а старшие байты (ah и прочий eax) - там будет ненулевой мусор, на который BOOL, вобравший в себя результат bool, среагирует как на eax!=0 и возникнет ошибка.

Мы должны были бы внутри последнего if перейти на ветку с eax==0 (Not equals), а перешли на ветку с eax!=0 (Equals), потому что функция CompareInt вернула нам только al равным 0, а старшие (мусорные) байты в eax внутри функции CompareInt при этом (ошибочно?) не были установлены в 0.

UPD3: Кстати, скомпилировал этот код древним (2006 г.) Borland Builder C++, все биты eax при возврате false внутри функции CompareInt явно устанавливаются в 0 путем xor eax,eax - поэтому ошибки нет.

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 08.02.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Microsoft Office для дома и учебы 2019 (лицензия ESD)
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год.
Microsoft Office 365 Бизнес. Подписка на 1 рабочее место на 1 год
Microsoft 365 Apps for business (corporate)
Microsoft 365 Business Basic (corporate)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
Компьютерная библиотека: книги, статьи, полезные ссылки
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100