g++ release 编译时,什么编译参数可以让它处理 try-catch

时间:2022-03-17 00:37:36
try
{
    // 这是 mysql++ 执行数据库操作
    res = query.store(email);
}
catch (const Exception& er)
{
    cout << er.what();

    return;
}


环境: windows + MinGW + gcc + CodeBlocks
症状: 以上代码,release 方式编译后,当数据库操作遇到异常,程序直接报错退出,而不执行 catch 区块。


请问:编译的时候增加什么参数,可以让 release 方式也能处理 try-catch 块。

29 个解决方案

#1


该回复于2011-01-24 08:46:18被版主删除

#2


windows, VC 下,我知道用 __try, __except 可以解决。
或者 VC 编译参数用:/EHa 也可以。

但是在标准 C++ 下,就不知道,请大家指教。

#3


-fexceptions

#4


-fexceptions ?

#5


-fexceptions 不对,不能解决这个问题

#6


我需要的参数是:

让编译器不优化 try-catch

#7


后面再跟个:catch(...),看看是啥异常先!

#8


-fexceptions 试试~~

#9


1、-fexceptions 选项一直都有
2、DEBUG 编译, catch (const Exception& er) 能捕捉到错误。Release 编译,就被 g++ 优化掉了。

#10


引用 9 楼 shove 的回复:
1、-fexceptions 选项一直都有
2、DEBUG 编译, catch (const Exception&amp; er) 能捕捉到错误。Release 编译,就被 g++ 优化掉了。

我不认为是release时优化掉了。
或许Release时还有别的错误,导致直接崩溃掉了。
试了catch(...)了?

#11


试过 catch(...) 了。
我上代码:

#include <mysql++.h>
#include <ssqls.h>

#include <iostream>

using namespace std;
using namespace mysqlpp;


int main(int argc, char** argv)
{
    mysqlpp::Connection conn(true);    //false 不抛异常
    conn.set_option(new mysqlpp::SetCharsetNameOption("gb2312"));
    conn.set_option(new mysqlpp::MultiStatementsOption(true));

    if (!conn.connect("test", "localhost", "root", "111111", 3306))
    {
        printf("Connect Fail.\n");

        return -1;
    }

    mysqlpp::Query query = conn.query("insert into t_users (telephone) values (%0q)");
    mysqlpp::SimpleResult sr;
    query.parse();

    try
    {
        sr = query.execute("0755-88888888");
    }
    catch (const BadQuery& er)
    {
        cout << "Query error: " << er.what() << endl;
    }
    catch (const BadConversion& er)
    {
        cout << "Conversion error: " << er.what() << endl << "\tretrieved data size: " << er.retrieved << ", actual size: " << er.actual_size << endl;
    }
    catch (const Exception& er)
    {
        cout << "Error: " << er.what() << endl;
    }
    catch (...)
    {
        cout << "Error: ";
    }

    conn.disconnect();
    getchar();

    return 0;
}

telephone 字段我故意设为 varchar(5),让长度不足。

在 DEBUG 下,catch (const BadQuery& er) 就报错了。 报错是数据太长。
在 Release 下,几个 catch 都没反应,直接崩溃。

#12


BadQuery在哪个头文件里面?

#13


#include "mysql++.h"这样试试吧。

#14


#include "mysql++.h"    // mysql 官方提供的 C++ 访问封装

#include <mysql++.h>

这样也对 catch 有影响吗?

#15


引用 14 楼 shove 的回复:
#include "mysql++.h" // mysql 官方提供的 C++ 访问封装

#include <mysql++.h>

这样也对 catch 有影响吗?

我只是在想会不会catch的时候找不到匹配的异常类型而已。

#16


哦,不会,找不到 mysql++.h 的话,

mysqlpp::Query query = conn.query("insert into t_users (telephone) values (%0q)");
mysqlpp::SimpleResult sr;

这些都不能用的,都在这个文件、以及这个文件包含的其他文件里面

#17


引用 12 楼 pengzhixi 的回复:
BadQuery在哪个头文件里面?


BadQuery 在 exceptions.h 中。
mysql++.h 包含了 exceptions.h。


引用 12 楼 pengzhixi 的回复:
#include "mysql++.h"这样试试吧。


这样试过了,还是一样的。 真的很奇怪

#18


那你就要确定store这个函数是否抛出了异常

#19


可以确定是编译优化掉了,

我用以下代码:

     int c = 0;

     try
    {
        int a = 99999999999;
        int b = 0;
        c = a / b;
    }
    catch (const Exception& er)
    {
        cout << "Error: " << er.what() << endl;
    }
    catch (...)
    {
        cout << "Error: ";
    }

    cout << c;

    getchar();


    return c;



启用了 -fexceptions 选项,运行也是直接崩溃。没有按预想执行 try-catch 块。
另外:如果没有 -fexceptions 选项的话,编译根本是通不过的,提示不允许出现 try-catch。

#20


贴出store函数的原型!
另外,/0不触发异常的,它触发的是中断,别在这一厢情愿用catch了。

#21


该回复于2011-01-25 08:38:25被版主删除

#22


同样的代码,在 VC 下编译,不管是 DEBUG, 还是 Release,都会有异常捕捉到。

在 g++ 下,用 CodeBlocks 编译,就不能捕捉到,直接崩溃。

---------------------------------------

网上搜了好多资料,怀疑是 mysql++ 处理异常有什么地方我没有搞懂。请高手们再仔细斟酌下,谢谢。

有篇帖子的问题与我的问题类似:
http://bbs.236z.com/thread-844747-1-1.html

#23


try
{
  // 这是 mysql++ 执行数据库操作
  res = query.store(email);
}
catch (const Exception& er)
{
  cout << er.what();

  return;
}
catch(...)
{
   cout << "未知异常" << endl;
}


异常不需要编译选项都会去处理的吧。

#24


该回复于2011-01-27 11:21:36被版主删除

#25


   测试了下,gcc下加不加-fexception 
  只要是用throw 出来的,catch(...)都能捕获,
 反之如一些:除零,读取无效内存,等都不能捕获,(在Window下面可以捕获)
 LZ可按这个思路去找找。
  
  这是我在网上找的,请LZ做参考:
 出自: http://hi.baidu.com/swdraven/blog/item/e50ee5268e49a21e8b82a103.html
 
 try
{
// 注意:下面这条语句虽然不是throw语句,但它在执行时会导致系统
// 出现一个存储保护错误的异常(access violation exception)
*p = 13; // causes an access violation exception;
}
catch(...)
{
//catch(…)能抓获住上面的access violation exception异常吗?
cout << "在catch(…) block中" << endl;
}
}

  请问上面的程序运行时会出现什么结果吗?catch(…)能抓获住系统中出现的
access violation exception异常吗?朋友们!和我们的主人公阿愚一样,
自己动手去测试一把!
结果又如何呢?实际上它有两种不同的运行结果,在window2000系统下用VC来测
试运行这个小程序时,发现程序能输出"在catch(…) block中"的语句在屏幕上,
也即catch(…) 能成功抓获住系统中出现的access violation exception异常
,很厉害吧!但如果这个同样的程序在linux下用gcc编译后运行时,程序将会出现
崩溃,并在屏幕上输出”segment fault”的错误信息。

主人公阿愚有点急了,也开始有点迷糊了,为什么?为什么?为什么同样一个程序在
两种不同的系统上有不同的表现呢?其原因就是:对于这种由于硬件或操作 系统出
现的系统异常(例如说被零除、内存存储控制异常、页错误等等)时,window2000
系统有一个叫做结构化异常处理(Structured Exception Handling,SEH)的
机制,这个东东太厉害了,它能和VC中的C++异常处理模型很好的结合上(实际上
VC实现的C++异常处理模型很大程度上建 立在SEH机制之上的,或者说它是SEH的
扩展,后面文章中会详细阐述并分析这个久富盛名的SEH,看看catch(…)是如何神
奇接管住这种系统异常出 现后的程序控制流的,不过这都是后话)。而在linux系
统下,系统异常是由信号处理编程方法来控制的(信号处理编程,signal proce
ssing progamming。在介绍unix和linux下如何编程的书籍中,都会有对信号处
理编程详细的介绍,当然执著的主人公阿愚肯定对它也不会放过,会深 入到unix
沿袭下来的信号处理编程内部的实现机制,并尝试完善改进它,使它也能够较好地
和C++异常处理模型结合上)。

那么C++标准中对于这种同一个程序有不同的运行结果有何解释呢?这里需要注意
的是,window2000系统下catch(…)能捕获住系统异常, 这完全是它自己的扩展。
在C++标准中并没有要求到这一点,它只规定catch(…)必须能捕获程序中所有通过
throw语句抛出的异常。因
此上面的这个 程序在linux系统下的运行结果也完全是符合C++标准的。虽然大家
也必须承认window2000系统下对C++异常处理模型的这种扩展确实是一个很 不错的
完善,极大得提高了程序的安全性。

#26


还是没有找到原因,郁闷中...

#27


还是觉得是 mysql++ 内部的问题,仔细分析了它的代码。

#28


只要是C++的编译器,都能够处理try-catch的!

#29


结贴几天后,一直心里总挂着这件事,现在终于找到原因了。

降低 gcc 的版本编译,终于可以处理 try-catch 了。
并不是 gcc 不能处理 try-catch,而是 mysql++ 的异常处理在高版本的 gcc 下有问题,mysql++ 的文档中有这么一段说明(可惜当初没有仔细看),浪费了不少时间。

官方说明:

Will it build under MinGW?
Yes. It does require at least GCC 3.4.5, however. Older versions don’t build MySQL++ correctly. Also, as of this writing, GCC 4 reportedly still has problems dealing with exceptions when thrown across a DLL boundary, so you may have to build MySQL++ as a static library if you wish to use GCC 4. This is no doubt an area the MinGW folk are concentrating on, so it may have changed by the time you read this.

#1


该回复于2011-01-24 08:46:18被版主删除

#2


windows, VC 下,我知道用 __try, __except 可以解决。
或者 VC 编译参数用:/EHa 也可以。

但是在标准 C++ 下,就不知道,请大家指教。

#3


-fexceptions

#4


-fexceptions ?

#5


-fexceptions 不对,不能解决这个问题

#6


我需要的参数是:

让编译器不优化 try-catch

#7


后面再跟个:catch(...),看看是啥异常先!

#8


-fexceptions 试试~~

#9


1、-fexceptions 选项一直都有
2、DEBUG 编译, catch (const Exception& er) 能捕捉到错误。Release 编译,就被 g++ 优化掉了。

#10


引用 9 楼 shove 的回复:
1、-fexceptions 选项一直都有
2、DEBUG 编译, catch (const Exception&amp; er) 能捕捉到错误。Release 编译,就被 g++ 优化掉了。

我不认为是release时优化掉了。
或许Release时还有别的错误,导致直接崩溃掉了。
试了catch(...)了?

#11


试过 catch(...) 了。
我上代码:

#include <mysql++.h>
#include <ssqls.h>

#include <iostream>

using namespace std;
using namespace mysqlpp;


int main(int argc, char** argv)
{
    mysqlpp::Connection conn(true);    //false 不抛异常
    conn.set_option(new mysqlpp::SetCharsetNameOption("gb2312"));
    conn.set_option(new mysqlpp::MultiStatementsOption(true));

    if (!conn.connect("test", "localhost", "root", "111111", 3306))
    {
        printf("Connect Fail.\n");

        return -1;
    }

    mysqlpp::Query query = conn.query("insert into t_users (telephone) values (%0q)");
    mysqlpp::SimpleResult sr;
    query.parse();

    try
    {
        sr = query.execute("0755-88888888");
    }
    catch (const BadQuery& er)
    {
        cout << "Query error: " << er.what() << endl;
    }
    catch (const BadConversion& er)
    {
        cout << "Conversion error: " << er.what() << endl << "\tretrieved data size: " << er.retrieved << ", actual size: " << er.actual_size << endl;
    }
    catch (const Exception& er)
    {
        cout << "Error: " << er.what() << endl;
    }
    catch (...)
    {
        cout << "Error: ";
    }

    conn.disconnect();
    getchar();

    return 0;
}

telephone 字段我故意设为 varchar(5),让长度不足。

在 DEBUG 下,catch (const BadQuery& er) 就报错了。 报错是数据太长。
在 Release 下,几个 catch 都没反应,直接崩溃。

#12


BadQuery在哪个头文件里面?

#13


#include "mysql++.h"这样试试吧。

#14


#include "mysql++.h"    // mysql 官方提供的 C++ 访问封装

#include <mysql++.h>

这样也对 catch 有影响吗?

#15


引用 14 楼 shove 的回复:
#include "mysql++.h" // mysql 官方提供的 C++ 访问封装

#include <mysql++.h>

这样也对 catch 有影响吗?

我只是在想会不会catch的时候找不到匹配的异常类型而已。

#16


哦,不会,找不到 mysql++.h 的话,

mysqlpp::Query query = conn.query("insert into t_users (telephone) values (%0q)");
mysqlpp::SimpleResult sr;

这些都不能用的,都在这个文件、以及这个文件包含的其他文件里面

#17


引用 12 楼 pengzhixi 的回复:
BadQuery在哪个头文件里面?


BadQuery 在 exceptions.h 中。
mysql++.h 包含了 exceptions.h。


引用 12 楼 pengzhixi 的回复:
#include "mysql++.h"这样试试吧。


这样试过了,还是一样的。 真的很奇怪

#18


那你就要确定store这个函数是否抛出了异常

#19


可以确定是编译优化掉了,

我用以下代码:

     int c = 0;

     try
    {
        int a = 99999999999;
        int b = 0;
        c = a / b;
    }
    catch (const Exception& er)
    {
        cout << "Error: " << er.what() << endl;
    }
    catch (...)
    {
        cout << "Error: ";
    }

    cout << c;

    getchar();


    return c;



启用了 -fexceptions 选项,运行也是直接崩溃。没有按预想执行 try-catch 块。
另外:如果没有 -fexceptions 选项的话,编译根本是通不过的,提示不允许出现 try-catch。

#20


贴出store函数的原型!
另外,/0不触发异常的,它触发的是中断,别在这一厢情愿用catch了。

#21


该回复于2011-01-25 08:38:25被版主删除

#22


同样的代码,在 VC 下编译,不管是 DEBUG, 还是 Release,都会有异常捕捉到。

在 g++ 下,用 CodeBlocks 编译,就不能捕捉到,直接崩溃。

---------------------------------------

网上搜了好多资料,怀疑是 mysql++ 处理异常有什么地方我没有搞懂。请高手们再仔细斟酌下,谢谢。

有篇帖子的问题与我的问题类似:
http://bbs.236z.com/thread-844747-1-1.html

#23


try
{
  // 这是 mysql++ 执行数据库操作
  res = query.store(email);
}
catch (const Exception& er)
{
  cout << er.what();

  return;
}
catch(...)
{
   cout << "未知异常" << endl;
}


异常不需要编译选项都会去处理的吧。

#24


该回复于2011-01-27 11:21:36被版主删除

#25


   测试了下,gcc下加不加-fexception 
  只要是用throw 出来的,catch(...)都能捕获,
 反之如一些:除零,读取无效内存,等都不能捕获,(在Window下面可以捕获)
 LZ可按这个思路去找找。
  
  这是我在网上找的,请LZ做参考:
 出自: http://hi.baidu.com/swdraven/blog/item/e50ee5268e49a21e8b82a103.html
 
 try
{
// 注意:下面这条语句虽然不是throw语句,但它在执行时会导致系统
// 出现一个存储保护错误的异常(access violation exception)
*p = 13; // causes an access violation exception;
}
catch(...)
{
//catch(…)能抓获住上面的access violation exception异常吗?
cout << "在catch(…) block中" << endl;
}
}

  请问上面的程序运行时会出现什么结果吗?catch(…)能抓获住系统中出现的
access violation exception异常吗?朋友们!和我们的主人公阿愚一样,
自己动手去测试一把!
结果又如何呢?实际上它有两种不同的运行结果,在window2000系统下用VC来测
试运行这个小程序时,发现程序能输出"在catch(…) block中"的语句在屏幕上,
也即catch(…) 能成功抓获住系统中出现的access violation exception异常
,很厉害吧!但如果这个同样的程序在linux下用gcc编译后运行时,程序将会出现
崩溃,并在屏幕上输出”segment fault”的错误信息。

主人公阿愚有点急了,也开始有点迷糊了,为什么?为什么?为什么同样一个程序在
两种不同的系统上有不同的表现呢?其原因就是:对于这种由于硬件或操作 系统出
现的系统异常(例如说被零除、内存存储控制异常、页错误等等)时,window2000
系统有一个叫做结构化异常处理(Structured Exception Handling,SEH)的
机制,这个东东太厉害了,它能和VC中的C++异常处理模型很好的结合上(实际上
VC实现的C++异常处理模型很大程度上建 立在SEH机制之上的,或者说它是SEH的
扩展,后面文章中会详细阐述并分析这个久富盛名的SEH,看看catch(…)是如何神
奇接管住这种系统异常出 现后的程序控制流的,不过这都是后话)。而在linux系
统下,系统异常是由信号处理编程方法来控制的(信号处理编程,signal proce
ssing progamming。在介绍unix和linux下如何编程的书籍中,都会有对信号处
理编程详细的介绍,当然执著的主人公阿愚肯定对它也不会放过,会深 入到unix
沿袭下来的信号处理编程内部的实现机制,并尝试完善改进它,使它也能够较好地
和C++异常处理模型结合上)。

那么C++标准中对于这种同一个程序有不同的运行结果有何解释呢?这里需要注意
的是,window2000系统下catch(…)能捕获住系统异常, 这完全是它自己的扩展。
在C++标准中并没有要求到这一点,它只规定catch(…)必须能捕获程序中所有通过
throw语句抛出的异常。因
此上面的这个 程序在linux系统下的运行结果也完全是符合C++标准的。虽然大家
也必须承认window2000系统下对C++异常处理模型的这种扩展确实是一个很 不错的
完善,极大得提高了程序的安全性。

#26


还是没有找到原因,郁闷中...

#27


还是觉得是 mysql++ 内部的问题,仔细分析了它的代码。

#28


只要是C++的编译器,都能够处理try-catch的!

#29


结贴几天后,一直心里总挂着这件事,现在终于找到原因了。

降低 gcc 的版本编译,终于可以处理 try-catch 了。
并不是 gcc 不能处理 try-catch,而是 mysql++ 的异常处理在高版本的 gcc 下有问题,mysql++ 的文档中有这么一段说明(可惜当初没有仔细看),浪费了不少时间。

官方说明:

Will it build under MinGW?
Yes. It does require at least GCC 3.4.5, however. Older versions don’t build MySQL++ correctly. Also, as of this writing, GCC 4 reportedly still has problems dealing with exceptions when thrown across a DLL boundary, so you may have to build MySQL++ as a static library if you wish to use GCC 4. This is no doubt an area the MinGW folk are concentrating on, so it may have changed by the time you read this.