簡體   English   中英

為什么在C11中不能將與bool進行比較轉換為bool?

[英]Why doesn't comparison with bool convert to bool in C11?

給出以下C11代碼:

int a = 1234;

bool b = (bool)a; // equivalent to (a != 0) or (a != false) which evaluates to 1 or true

if (a) // equivalent to if(a != 0) or if (a != false) which evaluates to 1 or true
  printf("a\n");

if (a == (bool)true) // should be equivalent to if(!(a == false)) or if (a != false)
  printf("a == (bool)true\n");

我知道true是#define true 1bool顯然不是普通的整數類型,因為(bool)0.1值計算為1,而強制轉換為int的結果將為0。

1)為什么沒有true定義為(bool)1 這將允許編譯器至少輸出警告。

2)為什么我的示例中的整數沒有轉換為bool ,以致a == (bool)true會評估為(bool)a == (bool)true ,這實際上是正確的?

為什么在C11中不能將與bool進行比較轉換為bool?

_Bool是最低的級別,等於運算符==指定其_Bool操作數提升為int @說故事的人


_Bool的等級應小於所有其他標准整數類型的等級。 C11§6.3.1.11

(相等運算符)如果兩個操作數都具有算術類型,則執行常規的算術轉換。 §6.5.94

(通常是算術轉換)...對兩個操作數§6.3.1.81都執行整數提升。

(整數提升)如果一個int可以表示原始類型的所有值...該值將轉換為一個int ...§6.3.1.12


OP的代碼示例沒有與bool的比較。

// int compared to int: false since a == 1234 and that is not equal 1
if (a == true)  

相反,本來可以

// int compared to _Bool: false since a == 1234 and that is not equal to 0 or 1
if (a == b) 

使用int == _Boolint == shortint == signed char ,會發生相同的情況。 較低級別的操作數被提升為int


1)為什么沒有真正定義為(bool)1? 這將允許編譯器至少輸出警告。

為什么? 幾年前的標准委員會決定。 當引入_Bool ,將true視為(int)1而不是(_Bool)1肯定會對現有代碼產生較小的影響。 (C99)。 這與其他子int常量(例如SHRT_MAX )一致,后者通常是int ,而不是short 在任何情況下,在大多數情況下,在進行進一步處理之前int/unsigned ,就像在這種比較情況下一樣。

不再需要(_Bool)1來允許編譯器提供警告。 可以使用各種分析工具制作提供警告的編譯器。 (_Bool)1 ,它可以簡化編譯器提供此類警告的過程。

2)為什么在我的示例中,該整數未轉換為bool ,使得a == true會評估為(bool)a == true ,而實際上是true?

作為true是一個(int)1 ,具有a == true ,兩個操作數都int _Bool在這里不適用。

2)[OP更新]為什么我的示例中的整數沒有轉換為bool ,使得a == true會評估為(bool)a == true ,而實際上會是true?

答案的最上面是這樣的: int中為true ,因此(bool)a在比較之前被提升為int ,因為int的等級高於_Bool

我知道true是#define true 1bool顯然不是普通的整數類型,因為(bool)0.1值計算為1,而強制轉換為int的結果將為0。

bool (實際上是_Boolbool是擴展為_Bool的宏)是整數類型。 它確實具有一個不尋常的功能,它不與任何其他類型共享:將任何非零值轉換為_Bool產生1

請注意,產生邏輯布爾值的運算符仍會產生值為01int結果。 由於隱式轉換,這通常不是問題。

1)為什么沒有true定義為(bool)1 這將允許編譯器至少輸出警告。

允許編譯器在需要時發出警告。 在比較警告truefalse將是一個不錯的主意。

2)為什么在我的示例中,該整數未轉換為bool ,使得a == true會評估為(bool)a == true ,而實際上是true?

a == true必須先將其操作數轉換為相同類型,然后才能進行比較。 這是通過通常的算術轉換完成的 規則(相當復雜)在N1570的 6.3.1.8節中進行了描述。 一個非常快速和不精確的總結是,較窄類型(較小整數轉換等級 )的操作數將轉換為另一個操作數的類型。 例如,當您比較intlong類型的表達式時, int操作數將提升為long _Bool最窄整數類型,所以它總是在比較促進除非它被另一個相比_Bool值。

僅為_Bool更改這些規則會造成混亂,並且確實不會給您帶來多少好處。

底線:請勿將相等值與falsetrue進行比較。 不要寫:

if (a == true)

寫吧:

if (a)

如果那是你的意思。 同樣,不要寫:

if (a == false)

寫吧

if (!a)

從評論中總結:

_Bool實際上是“僅”另一種無符號整數類型,其例外規則是,如果值不等於0(“ false”),則轉換為結果始終為1(“ true”)。

因為它是一個無符號整數,所以適用積分促銷規則。 即使將true定義為(bool)1 ,比較a == true也會導致實際比較1234 == 1 ,這始終是false

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM