2012-02-24 11 views
6

W komentarzach tutaj - https://stackoverflow.com/a/9393138/8047 - Odkryłem, że BOOL ma pewne nieoczekiwane zachowanie podczas ustawiania jego wartości z wartości int. W większości przypadków, jeśli wartość jest ustawiona na 0x1000, zostanie ona oceniona jako niespodziewanie jako FALSE.Implikacje wartości int nie "dopasowujących" - bool lub BOOL dla Objective-C?

NSLog(@"All zero? %d %d", (BOOL)0, (bool)0); 
NSLog(@"All one? %d %d %d", (BOOL)4095, (BOOL)4096, (BOOL)4097); // 4096=0x1000 or 8-bits 
NSLog(@"All one? %d %d %d", (bool)4095, (bool)4096, (bool)4097); 

Produces: 
All zero? 0 0 
All one? -1 0 1 
All one? 1 1 1 

Myślę, że to dziwne, ale potem znowu, nie rzucać od int do BOOL dużo tak. Jednakże:

  1. Czy to oznacza, że ​​bool być korzystne BOOL? Dlaczego lub dlaczego nie?
  2. Czy mogę używać

if (thatBool) {

        lub należy wolą

if (thatBool ? YES : NO) {

    i dlaczego?

Uwaga: To jest bardziej specyficzna wersja tej kwestii to - Objective-C : BOOL vs bool - ale myślę, że dodaje się do niego i nie jest duplikatem.

Odpowiedz

3

myślę że (BOOL)4096 oceniany na 0 jest prosty przepełnienie, tak jak (BOOL)256, ponieważ BOOL jest unsigned char. I myślę, że !! odlewania trik („podwójna negacja”) działa prawidłowo:

NSLog(@"%i", (BOOL)256); // 0 
NSLog(@"%i", !!256); // 1 

Oznacza to, że użyję BOOL zachować standardowy styl kodowania Kakao i po prostu oglądać za niebezpieczny rodzaj rzuca. Ekspresja thatBool ? YES : NO rani moje oczy, dlaczego chcesz to zrobić? :)

+0

Dowolny link na sztuczce castingowej !!? Te rzeczy są nieco trudne do wyszukania :) –

+0

To prosta [podwójna negacja] (http://www.google.com/search?q=c+double+negation), która powinna być łatwiejsza do wyszukania. – zoul

+0

Dzięki @Zoul, tak, to dość łatwe. Myślę, że "uważaj na niebezpieczne odlewy" ma rację. –

2

1) bool jest typem C++, BOOL jest obiektem C-tego. Casting z int do BOOL nie działa poprawnie, ponieważ YES tylko (BOOL)1 = (signed char)1 (= 0x001) i że nie jest równa (signed char)4 (= 0x100), na przykład.

2) Oba będą działać, drugi może być nieczytelny dla kogoś z niewielkim doświadczeniem w programowaniu. Wolę dobry stary test warunków bezpiecznego stanu c ze stałą po lewej, aby zapobiec przypadkowemu pominięciu jednego z równych znaków.

if (YES == isEnabled) { 

} 
+2

Po prostu dodając, że "if (thatBool?TAK: NIE) {"jest bezużyteczna, jest po prostu w środku jeśli (jeśli to jest!), To to samo. – fbernardo

+1

Lubię Yodę jeśli styl, zawsze wyobrażam sobie, że programista naprawdę tak mówi i jest po prostu przezabawny :) – JustSid

+0

I to jest bardzo praktyczne, faktycznie :-D – Alexander

0

Podczas korzystania z int, zawsze można jawnie ustawić BOOL, sprawdzając, czy int jest równe określonej wartości, np.

BOOL yesNo = ((int)4096 > 0); 
BOOL enableButton = (someInt >= 16); 

Innymi słowy, nie należy przekazywać int bezpośrednio do BOOL; przekształcić go w prawdziwe/fałszywe oświadczenie.