标签: exception-specification

为什么在编译时不检查C++异常规范?

我刚才读到,在C++ 11标准版本中,异常规范已被弃用.我以前认为指定你的功能可能是好的做法,但显然,不是这样.

在阅读了Herb Stutter引用得很好的文章之后,我不禁要问:为什么实际上是按照它们的方式实现了异常规范,为什么委员会决定弃用它们而不是在编译时检查它们?为什么编译器甚至允许抛出一个未出现在函数定义中的异常?对我来说,这听起来像是在说"你可能不应该指定你的函数返回类型,因为当你指定时int f(),但return 3.5;在它内部,你的程序可能会崩溃." (即强类型的概念差异在哪里?)

(由于typedefs中缺少异常规范支持,假设模板语法可能是Turing-complete,实现这个听起来很容易.)

c++ exception exception-specification c++11

8
推荐指数
2
解决办法
1297
查看次数

如何摆脱"忽略C++异常规范"的警告

我最近得到了一个已被其他人实现的dll.我必须在我的应用程序中使用它.在他们类的头文件中,他们有函数声明

void func1() throw (CCustomException);
Run Code Online (Sandbox Code Playgroud)

现在,当我编译它时,我收到警告,

忽略C++异常规范,除非指示函数不是_declspec(nothrow)

我阅读了MSDN - 文档,但无法理解它.另外,我不想因为它出现而禁用警告.我想知道我做错了什么而不是禁用它.

我认为我的功能,比如 从dll myfunc()访问func1()它没有那个Exception规范列表.因此,我尝试在我的函数中使用相应的异常规范列表,

void myfunc1() throw (CCustomException);
Run Code Online (Sandbox Code Playgroud)

但我仍然收到警告.什么是警告以及如何摆脱它?我在Windows XP中使用Qt 4.5.

c++ qt warnings exception-specification

7
推荐指数
1
解决办法
3298
查看次数

覆盖虚函数时的异常规范

请考虑以下代码:


class A
{
public:
    virtual void f() throw ( int ) { }
};

class B: public A
{
public:
    void f() throw ( int, double ) { }
};
Run Code Online (Sandbox Code Playgroud)

在编译时,它表示派生类B与A相比具有更宽松的抛出说明符.这有什么重要性?如果我们尝试交换它们的异常规范,例如A :: f()抛出int和double而B :: f()只抛出int,则不会出现错误.

c++ virtual-functions exception exception-specification

6
推荐指数
1
解决办法
5188
查看次数

为什么std :: map find()没有被声明为noexcept?

C++ 14标准定义了find()成员函数,std::map如下所示:

iterator find(const key_type& x);
const_iterator find(const key_type& x) const;
Run Code Online (Sandbox Code Playgroud)

为什么这些功能没有定义为noexcept?内部可能出错的地方,需要抛出一个异常或产生未定义的行为(除了没有找到一个元素,在这种情况下函数返回一个end迭代器并且无论如何都不需要抛出异常)?

c++ dictionary exception-specification noexcept

6
推荐指数
1
解决办法
707
查看次数

关于非投掷函数的混淆

我有两个关于非投掷功能的问题:

  1. 为什么要使一个函数不抛?

  2. 如何使功能不抛?如果函数内部的代码实际可能throw,那么我还应该让它不抛?

这是一个例子:

void swap(Type t1, Type t2) throw()
{
    //swap
}
Run Code Online (Sandbox Code Playgroud)

如果代码中swap根本不会抛出,我还应该追加throw()吗?为什么?

c++ exception-specification

5
推荐指数
1
解决办法
1618
查看次数

'typedef'中的异常规范是完全被禁止的还是仅仅是在顶级?

在C++ 14 Sec 15.4; 2中声明,......异常规范不应出现在typedef声明或别名声明中.

这意味着禁止以下内容:

typedef void (*fn)(int) noexcept;
Run Code Online (Sandbox Code Playgroud)

但是,措辞不会出现意味着令牌noexcept不能出现在typedef声明中的任何地方吗?

比如这些都是禁止的吗?

typedef void (*fn1)(void (*)(int) noexcept);
typedef decltype(std::declval<void (*)(int)noexcept>()) fn2;
Run Code Online (Sandbox Code Playgroud)

这两个都试图定义一个类型fn1,fn2并且能够指向一个函数,该函数接受一个函数的指针,该函数接受int并且不返回任何内容,同时承诺永远不会抛出异常.

因此在我的示例中,异常规范不适用于顶层类型fn1resp.fn2typedef这些函数可能接收的参数引入.

那么我应该逐字取15.4; 2,因此我的两个例子都无效?或者只是应用于禁止的类型定义,我的例子是正确的?

c++ typedef exception-specification c++14

5
推荐指数
1
解决办法
165
查看次数

尝试/ Catch或IF处理丢失的文件?

尝试/捕获异常或使用if语句来处理不同的结果是否更好?

我正在用Java编写一个简短的程序来复制文件以方便使用,并使用ifs来处理文件不存在的事件,并为每个方法声明抛出,但不要使用try/catch.

我应该回去用try/catches替换那些ifs和相关部分,还是这个"可接受的"编程"用于与小型用户社区共享?

java exception-specification

4
推荐指数
1
解决办法
2682
查看次数

异常规范,是否有用?

第一个免责声明:这不是导致"语言战争".对于我的报告,我真的需要这个(关于这个主题的澄清),我只想拥有有效而坚实的论据.
好的,所以这里有一个问题:
在C++中,异常规范已从C++ 11标准中删除,因为它被认为造成了更多的伤害而不是好处.
另一方面,在Java中,异常规范被视为好的和有用的东西.
在这两种语言中,这两个概念(具有异常规范的目的)是不同的,这就是为什么它们被这两个社区看得不同或者那些概念是相似/相同的?
哪一个?异常规范是好事还是坏事?或者它在Java中很好,因为(在这里我想看到一些原因)并且在C++中很糟糕,因为(原因在这里).
感谢任何有建设性帮助的人.

c++ java exception exception-specification exception-safety

4
推荐指数
1
解决办法
769
查看次数

基于经验的C++错误

最近,一位同事询问了我对C++代码中异常规范的使用的看法,并且我能够通过Herb Sutter挖掘这篇文章:一个实用的异常规范.像Herb Sutter一样,这篇文章是一本教育读物,但简短的回答是"不要这样做".

在摘要中,他提到了一首题为"实施之前的夜晚"的诗,其中,有效地,标准委员会鞠躬要求用户在最后一分钟添加一个功能,只是发现虽然它做了什么是要求,它并没有真正做他们想要的.是的,异常规范符合该法案.正如他所说,"这个功能在当时似乎是个好主意,而且正是有些人要求的." 如果这还不够,那么他会以类似的悲伤结果访问"出口".

所以问题是:如果你不想体验眼泪,那么C++的"特征"会被打破,不应该被使用.这可能是主观争吵的牺牲品,但我希望人们会引用一个特定的体验,其中部署该功能只会导致可测量的问题.更好的方法是引用像Sutter(或任何深入参与标准的人)这样的引人注目的文章,警告人们不要使用某个功能.

c++ export exception-specification

3
推荐指数
1
解决办法
275
查看次数

为什么异常规范无用?

我已经阅读了很多关于(不)使用throw(X)函数签名的论点,我认为它在ISO C++中指定的方式(并在当前编译器中实现)它相当无用.但是为什么编译器不能简单地在编译时强制执行异常正确性呢?

如果我编写包含throw(A,B,C)在其签名中的函数/方法定义,编译器在确定给定函数的实现是否异常正确时应该没有太多问题.这意味着功能体具有

  • 没有throw的其他比throw A; throw B; throw C;;
  • 没有函数/方法调用,抛出签名的限制性比throw (A,B,C);

,至少在外面try{}catch()捕捉其他抛出的类型.如果编译器在不满足这些要求时引发错误,那么所有函数都应该是"安全的",并且不需要运行时函数unexpected().所有这些都将在编译时得到保证.

void fooA() throw (A){
}

void fooAB() throw (A,B){
}

void fooABC() throw (A,B,C){
}


void bar() throw (A){

    throw A();   // ok
    throw B();   // Compiler error

    fooA();      // ok
    fooAB();     // compiler error
    fooABC();    // compiler error

    try{
       throw A();   // ok
       throw B();   // ok
       throw C();   // Compiler …
Run Code Online (Sandbox Code Playgroud)

c++ templates exception exception-specification

3
推荐指数
1
解决办法
397
查看次数