10 ms·
When noexcept?
- pjc50 10y agoThey still made it a runtime failure rather than a compile-time enforcement of no exceptions? What is the point of that?
- Rexxar 10y agoThe "nothrow" is not part of the function signature, probably in order not to break retro-compatibility. Without this, "nothrow" cannot be enforced reliably at compile time. And I think they don't want to add a new sort of undefined behaviour if a function from a linked module doesn't respect the nothrow promise at runtime.
- maxlybbert 10y agoYou are right, even nothrow doesn't fix the weirdness with signatures. However, nothrow allows a program to change behavior based on whether a function it will call will throw exceptions. That wasn't available under the old exception specification mechanism.
- maxlybbert 10y agoOne of the ground rules for the old exception specifications was that it had to be possible to link code compiled at different times. Which meant that there might never be a moment when the compiler had access to all the source code. And, given that most code did not have exception specifications, the only way to enforce them at compile time would have been to require them on all functions. I didn't follow the development of noexcept, so I can only guess at the motives. By and large, there were three complaints about exception specifications that I am familiar with: (1) by requiring stack unwinding when a no-throw specification was violated, they often caused worse performance (or, at least, didn't allow an optimization opportunity); (2) generally, the important question is whether a function might throw, not which exceptions it might throw; and (3) the rules around when exception specifications affect a function's signature -- e.g., does a pointer to a function have to match the specification exactly? -- were convoluted. I think it was reasonable for the Committee to focus on those issues.
- gpderetta 10y agoA possible solution would have been optional static enforcement of exception specifications plus fallback on the existing dynamic enforcement. Existing unmarked functions would be expeced to possibly throw everything, while functions with throw specifications would be statically checked. You can call the later from the former, but to do the reverse you need an explicit try/catch. Some form of throw(auto) would enable automatic deduction of exception specifications for e.g. template code. Dyanamic exception specifications will be removed fron the language in c++17, so the synax is open to be reused for such a feature in the future.
- palunon 10y agoThe problem is C code. You know it won't throw, but there will never be any exception specification on it.
- praptak 10y agoThere is also the nuclear option of telling the compiler not to use exceptions at all: -fno-exceptions. In the 3+ years I'm working in C++ without exceptions, I haven't missed them once.
- setra 10y agoSo how does this actually work with instances that would throw one? Are the standard libraries not very dependent on them?
- jeffinhat 10y agoA lot of large C++ shops re-implement much of the standard library, often to add niche features that don't make sense as a standard. I believe replacing the allocator in a lot of the standard data structures to a non-throwing one will get you pretty close to non-throwing.
- pjc50 10y agoThe standard libraries tend to only use them for fatal conditions such as out of memory. The standard library can compile with no-exceptions (see https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_except... ); if you mix no-exception and exception-using code, what happens is implementation-dependent but usually involves crashing.
- blub 10y agovector::at & co and std::stoi & co will throw. Big one: optional will throw.
- brandmeyer 10y agostd::function can throw, too
- vog 10y agoI couldn't agree more! When I first used Qt, I wondered how such a large framework could get along without exceptions. After writing some non-trivial Qt programs, I still noticed that there is really no need for exceptions, except when interfacing non-Qt libraries, where I simply caught and handled the exceptions in a small wrapper. Finally, I got it: Qt uses the Null-Object pattern (not to be confused with Null values!) consistently, which is really in almost all cases the more elegant solution: https://en.wikipedia.org/wiki/Null_Object_pattern https://en.wikipedia.org/wiki/Null_Object_pattern
- jeffinhat 10y agonoexcept is a messier than const because it's not straightforward to assess if code you rely on should be throwing or not since that's an implementation detail versus a contract around data ownership. This makes maintenance hard as implementations change. It'd be nice to see compilers infer the exception behavior themselves and do these optimizations when appropriate.
- alschwalm 10y agoIt is probably also worth noting that there is a good optimization opportunity when using noexcept move constructors. std::vector::push_back has a strong exception safety guarantee, so the normal behavior when the vector is at capacity is to create a new buffer and copy construct each item in the vector into it. If the copy constructor of any element throws, the original buffer is still in a coherent state. If the type has a move constructor that is noexcept, then each element can be move-constructed without fear of an exception occurring. For many types, this is vastly more efficient.
- blub 10y agoMy dream exception-related feature would be compile-time verification of noexcept. I don't care what gets thrown, because it's in the end going to be an std::exception (this is the part that Java messed up) I do care if a function will throw, because it radically changes its behavior. The problem I want to avoid is a silly function such as stoi throwing and having the exception propagated up to main, after which the whole program (orderly) shuts down. Right now this can be avoided only with careful exception design and making sure all exception "escape points" to C functions, message loops, etc are covered. Swift I think is one of the few languages supporting this.
- youdounderstand 10y agoGood luck when your program is dynamically linked to a library built with a different version of STL.
- brandmeyer 10y agoWouldn't this run afoul of the ODR, anyway?
- blub 10y agoI don't think so, ODR applies per program, the library and main program are separate. Object layouts will be likely different and the main program will probably crash.
- brandmeyer 10y agoNot so: The Standard doesn't have anything to say about the differences between static and dynamic libraries, or the differences between a .exe and its .dll's (or .so's). The program is composed of all the things that link into it as far as the ODR is concerned. The breakage from mixing different library versions (say, MSVCRT versions, for example) is a direct result of violating the ODR.
- 10y ago
- makecheck 10y agoThe entire concept of an unending exception chain seems flawed to me, and having to carefully annotate or check everywhere is still error-prone for programmers. It ought to be possible to create impenetrable exception boundaries, such as: - A compilation unit / file. - Something identified as a “library” (perhaps based on namespace). - The program itself. If I want my “library” to automatically trap all exceptions that I throw, I should be able to. I shouldn’t have to worry that entire programs may crash because of mistakes from exceptions. Similarly, a programmer should be able to say, ONCE (regardless of any functions added in the future), “trap all exceptions from code in this file using this function” and be done with it. And, if the language had been designed with this kind of visibility into exceptions, one would also have more useful information at the time they are trapped. For instance, obviously exceptions propagating all the way to main() have very little useful context but knowing that an exception is trapped in a file scope would be huge for debugging.
- jstimpfle 10y agoEntire programs can crash from a bad library, whether there are exceptions or not. If you need more isolation, maybe you can make a design based on restartable servers.
- youdounderstand 10y agoThere are real use cases where you need granular control, like implementing WinRT components on Windows. Basically, anytime you need to have a barrier between error code-based and exception-based code, or at ABI boundaries.
- pjc50 10y agoAnd this is why the people who wrote this code base I'm maintaining have manual stack-tracing code for the application - so whenever an exception is constructed of certain types we can dump its call location into the logs. Otherwise exceptions just appear as weird nonlocal flow control that loses information. GCC users have backtrace_symbols() for this. (It was an interesting exercise to see how much of the ARM stack unwinding I could do in C++ rather than assembler; I managed it with only one asm instruction to get the link register and a lot of instruction-decoding C++)
- leeter 10y agoThese are my uses for unconditional noexcept, they are not all encompassing but they work for me, in all cases the exception guarantee of the code should be noted: * Code that will never throw an exception * Code where throwing an unanticipated and therefore uncaught exception should trigger a failfast and crashing is not only the right behavior but the desired behavior. This should be the rarest of cases, but it does happen. * Code that is called across an ABI boundary that it is not safe for an exception to cross. This is the most common case as OS callbacks fit this. This should be noexcept because having the exception propagate across exception unaware code causes bad things to happen, it's also undefined behavior to boot.
- deleted 10y ago[deleted]