warning: dynamic exception specifications are deprecated in C++11

Hi,
I get this warning with gcc 7.2.1, see
http://my.cdash.org/viewBuildError.php?type=1&buildid=1330451
I don’t understand the code generating it so I don’t know how to fix it. Any suggestion?
Simon

Hi Simon,

From what I’m seeing, the warnings are generated by various files from ITK.
This comes from the fact that exception specification is deprecated since C++11 (see this post for some discussion about it) so writing function like:
virtual void MultiThreadingInitialize(void) throw ( ExceptionObject );
will generate warnings.

HTH,

Tim

Thanks. I had seen that but I do not really understand why would someone retrict the exceptions that a function can throw. My suggestion is to just remove all dynamic exception specifications from the ITK code rather than having yet another compiler specific variable. Would someone from Kitware agree with that change?

@simon.rit : In general ITK is really conservative when it comes to modifying compilation options as it can break things badly. In this case, I don’t think there is any reason to worry too much about it since it has even been removed from the C++ standard in C++17, so I think we could go either way. If a macro is added, it should check that __cplusplus >= 201703L. Clang tidy apparently has a checker to replace this call, so it shouldn’t be too difficult either way (see here). Could you submit a patch on gerrit to correct that issue? There is no request build: cpp17 command set up yet to request c++ 17 builds on the dashboards, but I will look into adding this.

@simon.rit: I added a set of dashboards (Linux, Windows, MacOSX) that can compile ITK with C++17. To request these builds, on gerrit you need to type request build: cpp17 (see here). I am in the process of testing that it works, and I will update this topic when testing is done.

@fbudin: ok great, thanks. I’ll submit a patch tomorrow, I won’t be able to do it tonight.

I believe these exception type specification should be removed. If a method throws an exception which is not specified, then the program is suppose to immediately about. This would not be good behavior.

However, the no throw specification is still quite useful when you want to ensure that code is exception safe or writing a class destructor.

Yeah, +1 to remove dynamic exceptions. Also it doesn’t add much value specifying to throw a generic ExceptionObject. I like the text in the standard referenced there, either the function might throw any exception (the default) or it doesn’t. In the later case, we tag the function with noexcept (since c++11) or the empty throw().

Just as an update, requesting a build with request build: cpp17 worked for the one patch I tried it on.

Ok, I submitted it a patch:
http://review.source.kitware.com/#/c/22844/
Let me know if I didn’t do the cpp17 build request correctly

Thanks @simon.rit! I have commented in gerrit, proposing to change the name of the macro, from ITK_NOEXCEPT_OR_THROW to just ITK_NOEXCEPT. The macro was there before your patch, but seems like a good opportunity to improve it.

The or_throw bit is confusing for the reader, is the function noexcept or throwing? Clearer would be ITK_NOEXCEPT_OR_EMPTY_THROW but it is not pleasant to read at all. I think the macro should state the purpose, not the implementation details of the language.

1 Like

Actually, ITK_NOEXCEPT is already defined in itk_compiler_detection.h whereas ITK_NOEXCEPT_OR_EMPTY_THROW is defined in itkMacro.h. @blowekamp @matt.mccormick : Any historical knowledge about why this seem to be defined twice, under different names?

The name for the macro ITK_NOEXCEPT_OR_THROW must not change. Supporting multiple legacy names is going to be significantly more confusing than the current name you don’t get (yet).

You can see where the naming came from by looking at the code:

This macro produces the proper function specification for C++03, and C++11. I’d blame C++03 for the convention of having to use “throw()” to specify no exception.

ITK_NOEXCEPT does not provide a C++03 implementation:

ITK_NOEXCEPT follows CMake’s compiler detection module, while ITK_NOEXCEPT_OR_THROW was defined for ITK’s compatibility needs.

2 Likes

@blowekamp Don’t you think having two macros that do basically the same thing is confusing? Which one should an ITK developer use? Or in which case should one or the other be used? There is no documentation in the source code or in the Software Guide for these macros.
Looking at where ITK_NOEXCEPT_OR_THROW is used, it seems that it is used in files handling exceptions (e.g. itkExceptionObject.cxx).

+1 for making exclusive use of ITK_NOEXCEPT and marking ITK_NOEXCEPT_OR_THROW as deprecated. We cannot remove ITK_NOEXCEPT_OR_THROW altogether because of backwards compatibility.

I do prefer the naming of ITK_NOEXCEPT, but the behavior of ITK_NOEXCEPT_OR_THROW is needed for C++03 compatibility.

Its not known to me if every case where there is an ITK_NOEXPECTa throw() would work in C++03. Likely a C++11 enthusiast added the ITK_NOEXPECT in ITK code to address C++11 warnings so the code difference was probably unintentional.

The source of ITK_NOEXCEPT is in itk_compiler_detection.h which is generated by CMake’s WriteCompilerDetectionHeader module, then committed to ITK. So modification of that macro or file is problematic.

I believe there other duplications of macros in itkMacro and in itk_compiler_detection.h. In general I think we should prefer what is in itkMacro over itk_compiler_detection. What is in itkMacro we are able to customize and update to ITK’s needs vs what is in the germinated code. I would almost say what in in itk_compiler_detection should be an implementation detail, and the public interface should be in itkMacro.h.

Thanks! I didn’t know how itk_compiler_detection.h was generated. @brad.king : Is there a way when calling WriteCompilerDetectionHeader in CMake to detect if Dynamic exception specifications have been removed from cpp17 (i.e. throw(typeid, typeid, ...) is deprecated or removed)?

Not to hijack the thread, but… why bother supporting pre=C++11 at all at this point in time? For comparison: VTK, CMake, and GDCM all require C++11 now.

Sean

1 Like

@seanm One good reason for us to support pre-c++11 features is that on Windows, we support Python2.7, and it requires ITK to be built with Visual Studio 2008.

1 Like

The point was that we could just remove the throw().

Recalling a recent talk by a Visual Studio backend developer and confirmed in this post, noexcept currently actually results in decreased performance due to implementation details, so we could remove the macros from where they are applied altogether.

1 Like