2016-07-15 21 views
-2

看看下面的C++代碼:C++串(常量字符[1])到bool類型轉換 - 原因/解釋和後果

// imagine 10.000 lines if C++ here 

bool test() { 
    // imagine 300 loc here 
    return ""; 
} 

int main(int argc, char** argv) { 
    bool whaaaaaat = test(); 
    return 0; 
} 

當編譯這些行的結果是:

BUILD SUCCESSFUL (total time: 208ms) 

甚至沒有警告!

請確認:

  1. 「」 是由C處理++編譯器爲char [1]又名字符*
  2. 然後將其轉化爲bool
  3. 這始終是= 0 =>總是正確!

問: 當程序繼續下去,會不會有該程序的狀態,任何負面影響(破碎的記憶?)。

這個設置非常危險,編譯器至少應該給出警告!

+0

你改變什麼,如果'回報 「」 號;''來回報1;'?你會有同樣的感覺嗎?怎麼樣'返回2;'?零是錯誤的。其他一切都是真實的。 –

+0

問題是關於函數總是返回true,沒有編譯器的任何警告或錯誤,這只是簡明的例子。同意一個良好的編碼風格可以阻止它。 –

+0

哦!所以你認爲'#define MAX_FOO 30' ...'int getMaxFoo(){return MAX_FOO; }'應該給出一個警告或錯誤?!問題在於你的期望,國際海事組織。具有恆定返回值的函數完全是常規的。 –

回答

1

你基本上是正確的。

您的字符串文字char const[1]將衰減到char const*,並且與任何指針一樣,booleanisation會告訴您它是否爲null。這一個不是。

我通常傾向於同意這種隱式轉換是危險的,但僅僅是因爲你的程序的行爲可能不是你想要的那樣。沒有「破碎的記憶」。

+1

這是第一個也是最準確的答案(開頭) –

+0

你認爲gdb可能會受到影響嗎?我認爲至少netbeans IDE不喜歡它... –

+0

@MartinMeeser:我不明白爲什麼有什麼「不喜歡它」或「受到影響」。這完全是確定性和符合標準的代碼。 –

1

""由C++編譯器爲char[1]處理又名char**

""被視爲之一恆定char陣列。它是而不是char*相同,儘管在某些情況下它可以轉換爲const char*(常數是C++特有的)。

然後將其轉化到bool這始終是!= 0 =>總是true

正確這兩點。

當程序繼續下去,會不會有該程序的狀態,任何負面影響(破碎的記憶?)

對於這個絕對沒有後果:沒有內存泄漏,沒有懸擺指針,或其他不好的事情。

1

它正確地解釋爲boolean conversions(隱式轉換中的一個):

積分,浮點,無作用域枚舉,指針的prvalue, 和指針到成員類型可以轉換爲一個prvalue類型 bool。

值爲零(用於積分,浮點和無限制枚舉),空指針和空指針對成員 值變爲false。所有其他值成爲真實。

爲您的代碼,""可能會衰減到指針(即const char*),這是不爲空,那麼結果將是true。對於指針,它只是檢查它是否爲空,並返回一個bool這是truefalse,它會沒事的(沒有「破碎的內存」:))。

1

沒有負面影響,只是不好的(太難以忽略)編碼風格。 我看到老多年這樣的代碼工作項目

assert(somethingIsRight && "Something is wrong!"); 
1

「」 是由C處理++編譯器爲char [1]又名字符*

在極不精確的術語,是啊之類的。更確切地說,""是一個const char[1],const char數組可以衰減到const char*,它指向第一個(僅在這種情況下)字符。

然後將其轉化爲bool

這始終是!= 0 =總是>真

究竟是,於兩者。

問題:當程序繼續時,程序狀態是否會有負面影響(內存損壞?)。

沒有破記憶,或任何其他負面影響。行爲已被很好地定義。該功能將有效地相同:

bool test() { 
    ""; 
    return true; 
} 

這種設置是非常危險的

我不同意。最多沒有意義。

問題是關於函數總是返回true,沒有編譯器的任何警告或錯誤,這只是簡明的例子。

我不認爲這是一個警告,更不是一個錯誤。

考慮一個接口,它是對不同類型進程的抽象,在成功時返回true。現在考慮實現這個接口,知道你的簡單過程永遠不會失敗,因此總是返回true。編譯器是否應該阻止你編寫這樣的實現?它是否應該用警告來糾纏你?不是在我看來。

您是否認爲gdb可能會受到影響?