gcc 指定任何软件异常的命令行选项可能会留下用“throw()”声明的函数。

发布于 2024-12-20 02:17:06 字数 565 浏览 1 评论 0原文

我正在用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

葬﹪忆之殇 2024-12-27 02:17:06

我对此表示例外:

gcc 生成的代码将会崩溃。

这完全是错误

像这样声明的函数:

 void func1();

如果抛出异常,它将导致堆栈展开到适当的捕获。如果没有适当的 catch,则程序退出(在这种情况下堆栈展开的天气是实现定义的(因此将 catch all 放在 main 中))。

一个函数声明如下:

void func2() throw(); // ie no throw.

如果异常逃逸该函数,则调用unexpected()。 unexpected 的默认操作是调用 abort() ,这会导致程序退出(注意:您可以用用户定义的函数替换unexpected,但它必须退出或抛出一个可以通过 throw 规范的替代异常(在本例中)这是不可能的))。

您想要的行为是默认行为(没有抛出规范)。投掷规范是一项失败的实验,因此已被弃用。无论如何你都不应该使用它们(除了 no- throw 之外)。

因此,如果您像这样定义函数,则可以获得正常工作的代码,但有异常:

void func3(); // Exceptions work fine.

但最好在 main() 中放置一个 catch

int main()
{
    try
    {
        // DoWork
    }
    catch(std::exception const& e)  // We can print a good error message with these
    {
        log(e.what()); 
        throw;                     // Not much you can do so re-throw for the OS.
    }
    catch(...)                     // Catch all other exceptions.
    {
        log("Unknown Exception");
        throw;                     // Not much you can do so re-throw for the OS.
    }
    // Catching forces the stack to unwind all the way to main()
    // Otherwise it is implementation defined whether it unwinds.
}

I take exception to this:

gcc-generated code will crash.

This is just plain wrong.

A function declared like this:

 void func1();

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:

void func2() throw(); // ie no throw.

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:

void func3(); // Exceptions work fine.

But it is best to put a catch in main()

int main()
{
    try
    {
        // DoWork
    }
    catch(std::exception const& e)  // We can print a good error message with these
    {
        log(e.what()); 
        throw;                     // Not much you can do so re-throw for the OS.
    }
    catch(...)                     // Catch all other exceptions.
    {
        log("Unknown Exception");
        throw;                     // Not much you can do so re-throw for the OS.
    }
    // Catching forces the stack to unwind all the way to main()
    // Otherwise it is implementation defined whether it unwinds.
}
野の 2024-12-27 02:17:06

这取决于您的编译器。使用 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).

暖心男生 2024-12-27 02:17:06

以下假设您抛出 在这个问题中概述

您的异常类型不起作用。

在 throw_exception 中,我们有这样一行:

text l_message;

我不知道 text 是什么,但我假设它是一个类似字符串的类。我同样会假设 test::_char 只是表达 char 的一种奇特方式。

所以我们有这个堆栈对象l_message,其类型为text。后来,我们得到了这样一行:

throw exc((const text::_char *)l_message);

既然你没有打算向我们提供 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:

text l_message;

I don't know what a text is, but I'll assume it is a string-like class. I will similarly assume that test::_char is just a fancy way of saying char.

So we have this stack object l_message which is of type text. Later, we have this line:

throw exc((const text::_char *)l_message);

Since you did not deign to provide us with a definition of text, again, I must make an assumption. I assume that text has an operator 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 by l_message disappears. That would be fine... if the class exc 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 the virtual const char* what() const throw() method. Then again, I'm surprised it let you compile your code without it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文