gcc 指定任何软件异常的命令行选项可能会留下用“throw()”声明的函数。
我正在用 C++ 编写一个使用 gcc 的程序。十二月。第五,由于一个奇怪的问题,我发布了一个问题( https://stackoverflow.com/a/8392854/837803 )。当软件异常留下未声明“抛出”规范的函数时,如下所示:
int foo();
或:
int foo() throw();
gcc 生成的代码将崩溃。
我想告诉 gcc,任何类型的软件异常都可能留下我编写的任何函数。我认为它是这样的:
int foo() throw(...);
但是:我不想在所有函数规范中都写 throw(...) 。我意识到我的程序大小会更大,但这对于本例来说不是问题。另外,我读到我建议的 gcc 行为违反了 ANSI。但这也没有问题。
在gcc的许许多多的命令行选项中,一定有一个是我在寻找的,但是我还没有找到。
我正在寻找什么选项?
I am writing a program using gcc in c++. On dec. 5th I posted a question because of a weird problem ( https://stackoverflow.com/a/8392854/837803 ). When a software exception leaves a function declared with no 'throw' specifications like this:
int foo();
or this:
int foo() throw();
gcc-generated code will crash.
I want to tell gcc that any kind of software exception could leave any function I write. I think it is something like:
int foo() throw(...);
BUT: I don't want to write throw(...) in all function specifications. I realise that my program size will be bigger, but that is not a problem for this case. Also, I have read that the behaviour of gcc that I am suggesting, is an ANSI violation. But that is no problem either.
Among the many, many, many command-line options of gcc, there must be one that I am looking for, but I haven't found it yet.
What is the option I am looking for?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我对此表示例外:
这完全是错误。
像这样声明的函数:
如果抛出异常,它将导致堆栈展开到适当的捕获。如果没有适当的 catch,则程序退出(在这种情况下堆栈展开的天气是实现定义的(因此将 catch all 放在 main 中))。
一个函数声明如下:
如果异常逃逸该函数,则调用unexpected()。 unexpected 的默认操作是调用 abort() ,这会导致程序退出(注意:您可以用用户定义的函数替换unexpected,但它必须退出或抛出一个可以通过 throw 规范的替代异常(在本例中)这是不可能的))。
您想要的行为是默认行为(没有抛出规范)。投掷规范是一项失败的实验,因此已被弃用。无论如何你都不应该使用它们(除了 no- throw 之外)。
因此,如果您像这样定义函数,则可以获得正常工作的代码,但有异常:
但最好在 main() 中放置一个 catch
I take exception to this:
This is just plain wrong.
A function declared like this:
If you throw an exception it will cause the stack to unwind upto an appropriate catch. IF there is no appropriate catch the program exits (weather the stack unwinds in this case is implementation defined (thus put a catch all in main)).
A function declared like this:
If an exception escapes this function then unexpected() is called. The default action of unexpected is to call abort() which causes the program to exit (Note: you can replace unexpected with a user defined function but it has to either exit or throw an alternative exception that can pass the throw specification (in this case that is not possible)).
The behavior you want is the default behavior (with no throw specification). Throw specifications were an experiment that failed and have thus been deprecated. You should not be using them anyway (apart from no-throw).
So you can get normal working code with exceptions if you define your functions like this:
But it is best to put a catch in main()
这取决于您的编译器。使用 gcc 默认设置,您可以直接抛出东西,而无需在原型中使用 throw(...) 。
当我想减少可抛出“事物”的数量时,我在原型中使用抛出声明。因此 int myfunc() throw(string) 只允许抛出字符串(或字符串的派生类)。
It will depend on your compiler. With gcc default settings you can just throw stuff without having throw(...) in the prototype.
I use throw declarations in the prototype when I want to reduce the amount of throwable 'things'. So int myfunc() throw(string) will only allow strings (or a derived class of string to be thrown).
以下假设您抛出 在这个问题中概述。
您的异常类型不起作用。
在 throw_exception 中,我们有这样一行:
我不知道
text
是什么,但我假设它是一个类似字符串的类。我同样会假设test::_char
只是表达char
的一种奇特方式。所以我们有这个堆栈对象
l_message
,其类型为text
。后来,我们得到了这样一行:既然你没有打算向我们提供
text
的定义,那么我必须再次做出假设。我假设text
为其定义了一个operator text::_char*
,它返回一个指向表示存储字符串数据的 C 风格字符串的指针,该字符串以 NULL 结尾。只有一个问题:该指针归
l_message
所有。当
l_message
脱离堆栈时,l_message
返回的指针就消失了。如果类exc
实际上将该字符串复制到内部缓冲区中,那就太好了。但事实并非如此。它只存储一个指针。不再指向有效内存的指针。这不是一个好主意。
异常需要是独立的。它应该拥有完成它应该做的任何事情所需的所有内存。
另外,您没有正确地从
std::exception
派生。具体来说,您必须重载virtual const char* What() const throw()
方法。话又说回来,我很惊讶它让你在没有它的情况下编译你的代码。The following assumes that you are throwing an exception of the type as outlined in this question.
Your exception type doesn't work.
In
throw_exception
, we have this line:I don't know what a
text
is, but I'll assume it is a string-like class. I will similarly assume thattest::_char
is just a fancy way of sayingchar
.So we have this stack object
l_message
which is of typetext
. Later, we have this line:Since you did not deign to provide us with a definition of
text
, again, I must make an assumption. I assume thattext
has anoperator text::_char*
defined for it which returns a pointer to a C-style string representing the stored string data, which is NULL-terminated.Only there's one problem: that pointer is owned by
l_message
.The moment
l_message
falls off the stack, the pointer returned byl_message
disappears. That would be fine... if the classexc
actually copied that string into an internal buffer. But it doesn't. It just stores a pointer.A pointer which no longer points to valid memory. That's not a good idea.
An exception needs to be self-contained. It should own all of the memory it needs to do whatever it is supposed to do.
Also, you did not properly derived from
std::exception
. Specifically, you have to overload thevirtual const char* what() const throw()
method. Then again, I'm surprised it let you compile your code without it.