Windows 7 64 SP1, 提升1.42, MS VS 2010旗舰版, C ++
这个精简代码使用这些开关在“Visual Studio x64命令提示符(2010)”中编译并运行良好:
cl /EHsc /W4 /nologo
#include <string>
using namespace std; // I know not to use.
int main() {
string sentence = "abc";
string word_found = "";
string::const_iterator it = sentence.begin();
while ( *it != ' ' && it != sentence.end() )
word_found += *it++;
}
但是,在VS IDE中进行编译后,运行时会因错误而崩溃:
Expression: string iterator not dereferencable
问题显然在于*it
中的( *it != ' ' && it != sentence.end() )
。我只需要将表达式短路,这样现在右手的表达式*it != ' '
就不会评估:
while ( it != sentence.end() && *it != ' ' )
然后运行良好。
但是为什么在从命令提示符编译原始代码后它运行完美?在这个子集派生的大得多的程序中没有其他异常行为。 string :: iterator不会导致同样的问题吗?
FWIW,这些是默认的MS VS命令行选项:/ZI /nologo /W3 /WX- /Od /Oy- /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Debug\test short.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /analyze- /errorReport:queue
为什么命令行编译器和IDE编译器会生成不同的可执行文件?是否有一个可以添加到命令提示符编译器的开关,它将使可执行文件的行为与从VS IDE编译时的行为方式相同
答案 0 :(得分:3)
这些运行时检查仅在 debug 版本中默认启用。你需要
通过使用the /MDd
or /MTd
option进行编译,使用其中一个调试运行时,或
通过将_ITERATOR_DEBUG_LEVEL
更改为1
(/D_ITERATOR_DEBUG_LEVEL=1
)来启用已检查的迭代器。