vcl方法+异常使用bcc64破坏内存

时间:2016-04-22 16:15:11

标签: 64-bit c++builder vcl

我的同事和我在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中做的事情。

1 个答案:

答案 0 :(得分:0)

严格来说,此代码没有任何问题,因此它必须是编译器错误。在Quality Portal提交错误报告。

话虽如此,你通常应该远离使用catch (...)。如果你要捕捉一个例外,至少要抓住你期望和愿意处理的事情:

catch (const char *)

让任何意外的事情通过,并在调用者链的更高处处理。

我不建议直接抛出字符串文字。最好将其包装在基于std::runtime_errorSystem::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;
}