簡體   English   中英

為什么在寫=而不是==時沒有收到警告?

[英]Why am I getting no warning when writing = instead of ==?

由於以下無效聲明,經過數小時的努力,他們終於找到了一個錯誤:

...
assert( variable = -0.5 );

顯然這應該是assert( variable == -0.5 ); :開發人員錯字。

我正在使用Visual Studio 2015進行編譯,並且確實在進行“ 0警告編譯”。

在沒有編譯器報告的任何警告的情況下,如何編譯這樣一個糟糕而危險的語句? 我們是否可以啟用編譯器選項來避免這種情況?

編輯 :甚至bool b = ( variable = -0.5 )不會產生任何編譯器警告

僅在使用/W4編譯級別時才警告條件表達式中的賦值,請參見this

因此,我在此代碼上使用在線MSVC編譯器(此PC上沒有VS 2015)對其進行了測試:

//Microsoft (R) C/C++ Optimizing Compiler Version 19.00.23506 for x86

#include <iostream>
#include <cassert>
int main(){
    int a;
    if (a = 2){
        std::cout << "Hello, world!\n";
    }
    assert(a = 3);
}

而此命令行為: source_file.cpp -o a.exe /EHsc /MD /W4 /IC:\\boost_1_60_0 /link /LIBPATH:C:\\boost_1_60_0\\stage\\lib ,兩行都發出了警告:

Warning(s):
source_file.cpp(9) : warning C4706: assignment within conditional expression
source_file.cpp(12) : warning C4706: assignment within conditional expression

顯然,在某些配置下,QT標頭qglobal.h使用QT_WARNING_DISABLE_MSVC(4706)禁用了此警告。

您沒有收到警告,因為它是完全合法且使用過的表達方式,例如,

while( (char c = getNextChar()) ) ...

因此,有些人在與const進行比較時,傾向於將const寫入lhs:

assert( -0.5 =  variable ); // this is an error
assert( -0.5 == variable ); // this is correct

請注意,當您有兩個要比較的非常量時,這不會縮放。 同樣,記住這個規則是否更容易記住== vs. =是有爭議的。

不幸的事實是,沒有通過靜態時間分析來避免此類錯誤的簡便方法。 考慮一下:

assert(var = possiblyUnsafeOp());
assert(var.otherOp() == something);

第一行證明,可能UnsafeOp()返回非null,並且在編寫測試時不能稱為錯誤。

您沒有警告,因為斷言可以測試分配,並且可以正常工作。 正如blobonat所說,更安全的代碼是: -0.5 = variable

該模式對於在找到0之前的列表中很有用,因此人們可能會故意寫出來,這就是為什么不生成警告的原因。 例如:

while(int a = nextElem()){
  //Do something with a
}

代替:

int a = nextElem();
while(a){
  //Do something with a
  a = nextElem();
}

或僅在函數返回非零(通常表示錯誤)時才執行某項操作

if(int res = myFunction()){
  //Do something only if non-0
}

在您的情況下,變量被分配了-0.5,並且在將其強制轉換為斷言期望將其固定為0的int時。您可以通過更改檢查的位置來避免這種情況,因為-0.5 = variable無效(但是-0.5 == variable ),因此除非您將兩個=符號放在一起,否則它不會編譯。

這種行為實際上可以派上用場,如果您想使用assert來評估一些復雜的語句,但必須事先進行一些分配,該怎么辦? 在這種情況下(現在想不出一個有效的示例,但我確實記得以此方式使用過),您可以執行以下操作:

assert(variable = -0.5, (do something with variable));

這顯然不能在發行版本中使用,但對於復雜的斷言可能會有所幫助。

暫無
暫無

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

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