大约10年前回到学校时,他们正在教您使用异常说明符。由于我的背景是其中的一位Torvaldish C程序员,他们顽固地避免使用C ++(除非被迫这么做),所以我只会偶尔散布C ++,并且当我这样做时,我仍然使用异常说明符,因为这就是我所教的。
但是,大多数C ++程序员似乎并不喜欢异常说明符。我已经阅读了各种C ++专家的辩论和论点,例如这些。据我了解,它可以归结为三点:
- 异常说明符使用与其余语言不一致的类型系统(“影子类型系统”)。
- 如果您的带有异常说明符的函数抛出了除您指定的内容以外的其他任何内容,则该程序将以不良的意外方式终止。
- 即将在即将发布的C ++标准中删除异常说明符。
我在这里错过什么还是所有这些原因吗?
我个人的意见:
关于1):那又如何。就语法而言,C ++可能是有史以来最不一致的编程语言。我们有宏,goto /标签,未定义/未指定/实现定义的行为的部落(ho?),定义欠佳的整数类型,所有隐式类型升级规则,特殊情况下的关键字,例如friend,auto ,注册,显式...等等。有人可能会写几本关于C / C ++怪异故事的厚书。那么,人们为什么要对这种特殊的矛盾做出反应呢?与语言的许多其他更危险的特征相比,这是一个较小的缺陷?
关于2):这不是我的责任吗?我可以用C ++编写致命错误的方法有很多,为什么这种特殊情况会更糟?除了编写throw(int)
然后抛出Crash_t之外,我还可以声明我的函数返回一个指向int的指针,然后进行一个狂野的,显式的类型转换,然后返回一个指向Crash_t的指针。C / C ++的精神始终是将大部分责任留给程序员。
那优势呢?最明显的是,如果您的函数尝试显式抛出除指定类型之外的任何类型,则编译器将给您一个错误。我认为有关此标准很明确。仅当您的函数调用其他函数而又抛出错误的类型时,才会发生错误。
来自确定性的嵌入式C程序世界,我当然希望更确切地知道函数会给我带来什么。如果有某种语言支持该功能,为什么不使用它呢?替代方案似乎是:
void func() throw(Egg_t);
和
void func(); // This function throws an Egg_t
我认为在第二种情况下,调用者有很大的机会忽略/忘记实现try-catch,而在第一种情况下则更少。
据我了解,如果这两种形式之一决定突然引发另一种异常,则程序将崩溃。在第一种情况下,因为不允许它抛出另一个异常,在第二种情况下,因为没有人期望它抛出SpanishInquisition_t,因此该表达式不会在应有的位置被捕获。
如果是后者,在程序的最高级别进行一些最后的捕获似乎并没有比程序崩溃更好的方法:“嘿,程序中的某处引发了一个奇怪的,未处理的异常”。一旦远离异常引发的地方,您将无法恢复程序,唯一可以做的就是退出程序。
从用户的角度来看,如果他们从操作系统中收到一个错误消息框,说“程序终止。地址为0x12345的Blablabla”,或者从您的程序中获得一个错误消息框,指出了“未处理的异常:myclass。 func.something”。该错误仍然存在。
随着即将到来的C ++标准,我将别无选择,只能放弃异常说明符。但是,我宁愿听到一些可靠的论据,说明它们为什么不好,而不是“圣洁已经说过了,事实就是如此”。也许对他们的争论比我列出的要多,或者对他们的争论比我所意识到的还要多?