18

Are dynamic exception specifications invalid in c++17? Like this

void f() throw(int);
msc
  • 33,420
  • 29
  • 119
  • 214
  • 4
    http://en.cppreference.com/w/cpp/language/except_spec – Richard Critten Dec 09 '17 at 09:35
  • 2
    [What are the new features in C++17?](https://stackoverflow.com/questions/38060436/what-are-the-new-features-in-c17) – Bo Persson Dec 09 '17 at 09:58
  • 8
    Not sure why this got downvoted. It's a very reasonable question. Everyone in the comments is basically saying RTFM which is super rude. What's the point of a Q&A site if everyone's gonna be rude and not help anyway? – void.pointer May 11 '18 at 13:43

2 Answers2

21

General C++ guidelines discourages to use of exception specifications with any version of C++ and new standard has removed this feature.

E.30: Don't use exception specifications

Reason

Exception specifications make error handling brittle, impose a run-time cost, and have been removed from the C++ standard.

Example
int use(int arg)
    throw(X, Y)
{
    // ...
    auto x = f(arg);
    // ...
}

If f() throws an exception different from X and Y the unexpected handler is invoked, which by default terminates. That's OK, but say that we have checked that this cannot happen and f is changed to throw a new exception Z, we now have a crash on our hands unless we change use() (and re-test everything). The snag is that f() may be in a library we do not control and the new exception is not anything that use() can do anything about or is in any way interested in. We can change use() to pass Z through, but now use()'s callers probably needs to be modified. This quickly becomes unmanageable. Alternatively, we can add a try-catch to use() to map Z into an acceptable exception. This too, quickly becomes unmanageable. Note that changes to the set of exceptions often happens at the lowest level of a system (e.g., because of changes to a network library or some middleware), so changes "bubble up" through long call chains. In a large code base, this could mean that nobody could update to a new version of a library until the last user was modified. If use() is part of a library, it may not be possible to update it because a change could affect unknown clients.

The policy of letting exceptions propagate until they reach a function that potentially can handle it has proven itself over the years.

Note

No. This would not be any better had exception specifications been statically enforced. For example, see Stroustrup94.

Note

If no exception may be thrown, use noexcept or its equivalent throw().

Marek R
  • 32,568
  • 6
  • 55
  • 140
  • 6
    Both a fellow named Bjarne an I saw the problems with dynamic exceptions when they were proposed. He told me in a phone conversation that a certain "big player", which he did not name, had refused to endorse the new standard unless they were included. – Jive Dadson Dec 09 '17 at 10:12
  • @JiveDadson That's interesting. It looks like not even the standards committee is immune to lobbying. – void.pointer May 11 '18 at 13:45
  • This is yet another reason to use the so-called `Exception-free` design pattern (for example `Qt` framework uses that) which means: **1.** there is not a single `try`, `catch` or `throw` anywhere in the source-codes. **2.** there is not any log about any error because there are none. **3.** there is only `invalid-pointer` crash (which could be caused by `out of memory` or using `null` as pointer). **note that** I refer to above as `invalid-pointer crash` not `invalid-pointer exception` since in C++ that will always result in a crash (and we can only attach to `Unhandled Exception` and dump it) – Top-Master Dec 01 '19 at 06:38
  • Do you know what reasoning the referenced `Stroustrup94` gives against static enforcement? – Aykhan Hagverdili Jan 10 '23 at 14:36
  • problem is code maintainability. If you specify what can be thrown then later if you need to do some changes in this function new exceptions may appear or some exception may disappear, this mean function specification may change. This also has impact on name mangling, so breaks library binary compatibility. Note Java has similar solution (if exception inherit specific base exception it must be listed in function definition) and now it is discourage to use base class which enforces that. – Marek R Jan 10 '23 at 15:24
4

They are officially invalid in C++17. However, Visual C++17 with C++/Language/C++ Language Standard set to ISO C++17 still allows them. Setting warning level to 3 or higher [properties/General/Warning Level/] gives the warning,

warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)

Note that throw() is still legal and is equivalent to the newly added noexcept.

Jive Dadson
  • 16,680
  • 9
  • 52
  • 65
  • I cannot imagine why this got a down-vote. Explain, and I'll fix the answer. – Jive Dadson Dec 09 '17 at 09:42
  • 2
    I am guessing, but could be that `throw()` is deprecated and should therefore not be recommended, could the tale of a "story" with no link. Perhaps even an explanation why they were a bad idea from the start, or simply a link to one of the counteless answers on this site where they answer that. :) – Tommy Andersen Dec 09 '17 at 09:48
  • 1
    Didn't downvote, but why is it a problem that Visual C++ 17 still "allows" it? First of all, it obviously cannot force its users to change all legacy code which uses exception specifications. Second, with `/W4`, you get a diagnostic message that says `warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)`. What more do you need? – Christian Hackl Dec 09 '17 at 09:51
  • @ChristianHackl personally I find it bad if Visual C++ 17 claims to be C++17 compliant, which I highly doubt though. But set to ISO C++17 mode, it should act according to the C++17 mode, which dictates that it has been removed from the language. – Tommy Andersen Dec 09 '17 at 09:52
  • 1
    @Tommy I am removing the part about the "story", which I learned in a telephone conversation with a Very Important Person when the feature was being considered. I am researching the /W4 thing. – Jive Dadson Dec 09 '17 at 09:54
  • 3
    @TommyAndersen: ISO C++ makes no distinction between errors and warnings. As long as there's a diagnostic message, conformance is reached. It's then up to the programmer to decide whether the code should be conformant or not. That's perfectly OK. Of course, there *are* problems with C++17 features not or not correctly implemented by the compiler, but failure to report diagnostic messages for exception specifications isn't one of them. – Christian Hackl Dec 09 '17 at 09:57
  • @JiveDadson: Properties > Configuration Properties > C/C++ > General > Warning Level. – Christian Hackl Dec 09 '17 at 10:00
  • 2
    @Tommy - StackOverflow is a tough audience. I try to help, and I get a raspberry for my efforts. Oh well. I have edited the answer. – Jive Dadson Dec 09 '17 at 10:06
  • By the way, `/W3` is sufficient to get the warning. One more thing: it's rarely a good idea to use a compiler with default settings. If you take GCC, for example, it allows illegal VLAs if you don't explicitly tell it to be `-pedantic`, and even then it's "only" a warning. – Christian Hackl Dec 09 '17 at 10:06
  • @JiveDadson Yes, StackOverflow audience may be tough. But I, for one, have learned more from my downvoters than from all my upvoters put together :-) – cmaster - reinstate monica Dec 09 '17 at 10:14
  • @cmaster - I welcome criticism. Anonymous jeers not so much. Whoever down-voted left no comment. I will get over it. :-) – Jive Dadson Dec 09 '17 at 10:17
  • 1
    @ChristianHackl Actually with the release on VS2017 15.5 the support for C++17 has been improved and [dynamic exception specifications now issue `warning C5040: dynamic exception specifications are valid only in C++14 and earlier; treating as noexcept(false)`](https://learn.microsoft.com/en-us/cpp/cpp-conformance-improvements-2017#noexcept_removal) if `/std:c++17` switch is applied. – user7860670 Dec 09 '17 at 11:16
  • @TommyAndersen Visual C++ does not claim to be C++17 compliant, more details can be fount at [Visual C++ Language Conformance page](https://learn.microsoft.com/en-us/cpp/visual-cpp-language-conformance). – user7860670 Dec 09 '17 at 11:19
  • @VTT - Thanks for that. I thought VS gave a notice when there was a new update. If so, I missed it. Now I'm all 15.5. – Jive Dadson Dec 09 '17 at 16:21