![](/img/trans.png)
[英]Why am I getting warning 'C6386' Buffer overrun while writing to 'ptr'?
[英]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.