17

Since noexcept was introduced and addressed many of the problems with throw(), there is now a reason for specifying whether a function does not throw an exception. While it is not a compile time restriction, it will enable some potential optimizations by the compiler, and if nothing else, a signalling, and documentation, value for the user of the function.

In light of this I was actually a bit surprised, when I browsed through the standard functions such as: std::time, std::timespec_get, and std::memcmp, and saw that none of them used the noexcept specifier. It is not like there are no functions at all using it, in the standard library, for instance the std::tie function uses it, and others as well. But a large portion of functions, do not use it.

I guess it makes sense for functions that have undefined behaviour in certain situations, such as std::strlen, since this will allow implementers more freedom.

But for functions where there are no specified situations which can lead to undefined behaviour, and which obviously do not throw exceptions, why would these functions not be declared using the noexcept specifier?

It cannot only be due to keeping similarity with the old C functions, since for instance std::timespec_get is a new function in C++11, so it must be for some other reason.

The compiler might very well be smart enough to detect that the functions will not throw exceptions, and as such be able to do the same optimizations. But in my opinion one of the best arguments for noexcept is the documentation value, that comes from it, which will be lacking, when it is missing.

Which leads me to my final hypothesis, that the missing noexcept specifiers in the standard library are really oversights, much like it was the case with the missing std::make_unique. But unlike the missing std::make_unique which was corrected (implemented) in C++14, the functions above, have still not (as of C++17) been made noexcept.

Does anyone know the reasoning behind the missing noexcept specifiers, or am I right in thinking that this is an oversight?

Tommy Andersen
  • 7,165
  • 1
  • 31
  • 50
  • 6
    You'd have to ask the comity. Keep in mind that once you declare a function `noexcept`, removing it would be a breaking change. You can always add it later while maintaining backwards compatibility. – François Andrieux Jun 07 '17 at 19:29
  • 7
    See the first paragraph [here](https://stackoverflow.com/a/20517333/4342498). Might be what you are looking for – NathanOliver Jun 07 '17 at 19:30
  • @NathanOliver that is actually an interesting post. However not only functions that have specified undefined behaviour lack the `noexcept` specifier, but also function that "cannot" or "must not" fail, can lack them. At least it appears such from my short investigation. – Tommy Andersen Jun 07 '17 at 19:34
  • @FrançoisAndrieux The point about potentially breaking backwards compatibility if introducing exceptions for the function, is actually really interesting, and not something I had thought about. But is it really likely with the `std::memcmp` function? I guess it could be. – Tommy Andersen Jun 07 '17 at 19:35
  • `timespec_get` is a C11 function that C++17 imported. – T.C. Jun 07 '17 at 19:38
  • 1
    @TommyAndersen Can you give me an example of a function that cannot or must not fail that is not marked with `noexcept`? Also [here](https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Re-noexcept) is a link to what the CPP core guidelines have to say about `noexcept`. – NathanOliver Jun 07 '17 at 19:40
  • @T.C. you mean C11 function? but yes you are actually correct, it slipped my attention. – Tommy Andersen Jun 07 '17 at 19:40
  • Right, also it's C++17. I got confused because you said it's in C++11 - and C++11 doesn't import anything from C11. – T.C. Jun 07 '17 at 19:40
  • @NathanOliver I guess the [`std::iswspace`](http://en.cppreference.com/w/cpp/string/wide/iswspace) could be such an example? – Tommy Andersen Jun 07 '17 at 19:42
  • @T.C. good point. – Tommy Andersen Jun 07 '17 at 19:44
  • @TommyAndersen That one has UB if you pass it something neither representable as a `wchar_t` nor equal to `WEOF`. – T.C. Jun 07 '17 at 19:45
  • 2
    If you think there are functions that really ought to be `noexcept`, but are not currently, and there would be no downsides to making them so (and I'm *not* saying there are no such functions), why don't you then write up a proposal for the standards committee to consider that includes your rationale(s) and submit it? The standard doesn't evolve by magic you know; it requires knowlegable and engaged members of the public to participate in order to make good progress :) – Jesper Juhl Jun 07 '17 at 19:56
  • 1
    There's also the reality that C++ library implementations often do not have control over the C library implementation, so adding C++-specific polishes to stuff from the C library is difficult (especially now that noexcept is part of the function type). – T.C. Jun 07 '17 at 20:12
  • I think that you got the primary reason. Many of the functions are C and thereby implicitly `noexcept`. To me it sounds a little crazy starting adding C++ modifiers – Jens Munk Jun 21 '17 at 10:18

1 Answers1

1

Rephrasing what you wrote above,

how can you guarantee noexcept when things are passed by pointers?

When you write your custom classes/functions, you can mark things noexcept without no guarantee of throwing no exception. But you probably do not want to do it when you are not absolutely sure that your function will not throw in any case.

kmkim85
  • 51
  • 1