我的同事和我在C ++ Builder程序中遇到了一个奇怪的错误,并将其归结为以下代码段:
#include <vcl.h>
#include <iostream>
void SIDE_EFFECTS() {
if (StrToFloat("1337")) {
throw "abc";
}
}
int _tmain(int argc, _TCHAR* argv[])
{
double innocent = StrToFloat("42");
std::cout << innocent << std::endl;
try {
SIDE_EFFECTS();
} catch (...) {
}
std::cout << innocent << std::endl;
return 0;
}
预期产出:
42
42
编译为64位/ ReleaseBuild / OptimizationsON时的实际输出:
42
1337
编译器(最新的10.1柏林版C ++ Builder):
Embarcadero C++ 7.20 for Win64 Copyright (c) 2012-2016 Embarcadero Technologies, Inc.
Embarcadero Technologies Inc. bcc64 version 3.3.1 (35759.1709ea1.58602a0) (based on LLVM 3.3.1)
互联网说[引证需要]错误总是在用户程序中,但从不在编译器或标准库中,所以请指教我们是否/我们在C ++ / C ++ Builder中做的事情。
答案 0 :(得分:0)
严格来说,此代码没有任何问题,因此它必须是编译器错误。在Quality Portal提交错误报告。
话虽如此,你通常应该远离使用catch (...)
。如果你要捕捉一个例外,至少要抓住你期望和愿意处理的事情:
catch (const char *)
让任何意外的事情通过,并在调用者链的更高处处理。
我不建议直接抛出字符串文字。最好将其包装在基于std::runtime_error
或System::Sysutils::Exception
的对象中。
#include <vcl.h>
#include <iostream>
#include <stdexcept>
void SIDE_EFFECTS() {
if (StrToFloat("1337")) {
throw std::runtime_error("abc");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
double innocent = StrToFloat("42");
std::cout << innocent << std::endl;
try {
SIDE_EFFECTS();
} catch (const std::runtime_error &) {
}
std::cout << innocent << std::endl;
return 0;
}
#include <vcl.h>
#include <iostream>
void SIDE_EFFECTS() {
if (StrToFloat("1337")) {
throw Exception("abc");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
double innocent = StrToFloat("42");
std::cout << innocent << std::endl;
try {
SIDE_EFFECTS();
} catch (const Exception &) {
}
std::cout << innocent << std::endl;
return 0;
}