2012-05-05 19 views
9

我有以下代碼:爲什麼當一個枚舉或int值作爲一個函數的bool參數傳遞時,gcc不會發出警告?

typedef enum 
{ 
    FOO, 
    BAR, 
    BAZ 
} foo_t; 

static void afunc(bool is_it_on) 
{ 
    /* do the job */ 
} 

int main(void) 
{ 
    afunc(BAZ); 
    return 0; 
} 

編譯此代碼不會產生任何警告信息,甚至向編譯器-Wall -Wextra選項。我甚至嘗試過使用-Wconversion選項,該選項不起作用,因爲boolenum似乎與g ++的大小相同。 (據我所知enum類型的規格沒有在規格中定義)

我已經梳理了gcc手冊並沒有發現任何關於它的信息。

問題:

  • 有沒有辦法迫使編譯器生成在這樣的情況下,一個警告?
  • 或者是這個隱式轉換是合法的C++規範?

編譯器,我使用:GCC 4.1.2


Editted

結論:

唯一可行的解​​決方案,這似乎定義一個新的類型來表示0或1,並用它代替bool

的代碼會像以下,和g ++抱怨類型轉換:

typedef enum 
{ 
    FOO1, 
    FOO2 
} foo_t; 

typedef enum 
{ 
    MY_FALSE, 
    MY_TRUE 
} my_bool_t; 

void foo(my_bool_t a) 
{ 
} 

int main(void) 
{ 
    /* 
     * gcc generates an error. 
     * error: cannot convert ‘foo_t’ to ‘my_bool_t’ 
     * for argument ‘1’ to ‘void foo(my_bool_t)’ 
     */ 
    foo(FOO1); 
    return 0; 
} 
+1

因爲C++」類型系統只適用於用戶定義的類型,對於內置類型它總是很糟糕。其C遺產的後果。 –

+0

是的,它似乎是如此。我決定typedef一個專門用於表示0或1的新類型,並用它來代替bool,這似乎是爲了表示_true_或_false_。 – orchistro

回答

10

是的,這些隱式轉換是完全合法的。

C++ 11個n3290草案,§4.12布爾轉換

算術,無作用域枚舉,指針,或指向構件類型的prvalue可以被轉換爲一個 prvalue bool類型。零值,空指針值或空成員指針值被轉換爲false; 任何其他值都轉換爲true。類型std :: nullptr_t的前值可以轉換爲 類型的前值bool;結果值是錯誤的。

有關這些轉換(對於算術類型)的警告可能會導致大量的警告,我不認爲這是可以處理的。

在C++ 11,可以使用範圍的枚舉防止隱式轉換:

這無法編譯由於缺乏一個轉換從Foobool

enum class Foo { ONE }; 

void tryit(bool b) { } 

int main() 
{ 
    tryit(Foo::ONE); 
} 
+0

謝謝你,馬特。如果它通過C++規範是合法的,我想實現我想要的唯一方法是爲項目鍵入一個新的布爾類型,以便項目的成員不會出現錯誤,如代碼段。 – orchistro

+0

不幸的是,gcc 4.1.2似乎不支持'範圍枚舉'。我想我應該訴諸於typedef解決方案,它實際上工作。 通常情況下,你不需要。但是在某些情況下,像你在重構其他人的代碼,沒有這種「嚴格的」類型檢查,你會感到抱歉。 也許我應該使用皮棉。 – orchistro

+0

@orchistro:如果可能,請嘗試在gcc上更新一個版本(我知道這並不容易......)。 gcc 4.1.x是一個相當古老的分支。 –

相關問題