2016-04-22 28 views
0

我和我的同事在C++ Builder程序有一個奇怪的錯誤,並煮下來到下面的代碼片段:VCL方法+異常損壞的內存bcc64

#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 B 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

嚴格來說,這段代碼沒有問題,所以它必須是一個編譯器錯誤。在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; 
} 
+0

在現實中,我們拋出其它/捕獲的東西。拋出一個字符串並捕捉一切,是我們試圖最小化這個例子並排除外部影響。我們將在Quality Portal上報告。 – mnagel