【问题标题】:C++: Indicating a function may throw [duplicate]C ++:指示函数可能会抛出[重复]
【发布时间】:2011-06-02 15:13:39
【问题描述】:

可能重复:
Is there a generally accepted idiom for indicating C++ code can throw exceptions?

您如何在代码中指出 C++ 函数何时可以抛出某些东西?我的意思不是通过文档,而是通过语法。

例如,我尝试在函数声明的末尾放置一个throw(std::exception),但这给了我一个警告,说“C++ 异常规范被忽略,除了指示函数不是 __declspec(nothrow)”,我猜这意味着编译器忽略了throw 并继续进行,就好像它不存在一样。

我还尝试在声明的末尾添加throw()(括号中没有任何内容),但是 - 与我的预期相反 - 这意味着函数预计永远不会抛出任何东西:“函数假定不会抛出例外,但确实如此”。

Atm 我使用throw(...) 在语法上指示函数可能会抛出,因为这不会给我任何错误或警告。对于我如何通过语法来表示这一点,您还有其他建议吗?

【问题讨论】:

    标签: c++ exception syntax coding-style


    【解决方案1】:

    你没有。异常说明符并不意味着“这是我可以抛出的”,它们的意思是“如果抛出除此之外的任何东西,请转到 std::terminate”。这种行为违反直觉,MSVC++ 不支持也不支持。

    C++ 的语义是你必须假设一个函数总是可以抛出。

    【讨论】:

    • 不,如果是动态异常规范,它将转到std::unexpected,而不是std::terminate
    • @Karl:我没有在那里给出技术答案——语义不一定是标准所说的。意外的默认行为是调用终止或中止(不记得到底是哪个),所以对于大多数用户来说,这意味着同样的事情。这里的重点是它是运行时检查,而不是编译时检查。
    • 我知道它是运行时的,但我一直在寻找一种方法来快速指示函数可能会抛出。尽管 C++ 允许所有东西都抛出,除非另有说明,但现实情况是大多数时候函数都不会抛出。这意味着应该让他们抛出的案例脱颖而出。
    • @Paul:根据我的经验,大多数函数 do 抛出。至少,std::bad_alloc.
    • @Paul:一个调用抛出函数的函数,也会抛出异常,除非它捕获到这些异常。大多数时候,某个地方的某个人正在调用std::basic_string<CharT>::append(或operator+= 等价)、std::vector<t>::push_back 或类似的东西。
    【解决方案2】:

    当涉及到异常规范时,大多数编译器都不符合标准。异常规范被视为 experiment that failed.
    例如:
    如果您有一个空白的异常规范,那么会调用什么? unexpected() 方法或 bad_exception 将被抛出,如果两者都按什么顺序?

     #include "stdafx.h"  
     #include <stdio.h>  
     #include <exception>  
     #include <iostream>  
    
    
    using namespace std;
    
    class A
    {
        public:
            int i;
    };
    
    void myunexpected () 
    {
        cerr << "unexpected called\n";
    }
    
    void doSomething(void) throw();
    void doSomething(void) throw()
    {
        A obj;
        obj.i= 100;
        throw obj;
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        set_unexpected (myunexpected);
        try 
        {
            doSomething();
        }
        catch (bad_exception be) 
        {
            puts("Caught something");
        }
        catch (A &obj) 
        {
            puts("Caught Integer");
        }
        return 0;
    }
    

    如果您在 Visual Studio 上运行此代码,您将看到异常刚刚被适当的处理程序捕获。

    总之,异常规范是一个失败的实验,最好避免它们。

    【讨论】:

    • VC++ 没有实现异常规范,除了空的 (throw()/nothrow)。
    【解决方案3】:

    基本上,throw 说明符毫无价值,不幸的是,在引入它们之后 发现,当前的编译器忽略了它们。它们已被弃用,质量库不包含它们。只是不要打扰他们。 C++0x 正式弃用它们,并且只有一个 noexcept 关键字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-08
      • 2020-02-27
      • 1970-01-01
      • 2021-03-22
      • 2021-03-12
      • 1970-01-01
      • 2013-04-03
      相关资源
      最近更新 更多