Opinions on dropping support for C++03

All of us would like to be able to use modern C++ when writing ITK. But some use cases prevent us from dropping support for pre-C++11 compilers.

One of the use cases is python 2 Windows binaries, which need to be compiled using Visual Studio 2008, which only knows C++03. As Matt pointed out, python 2 is still default on most Linux distributions and is worth supporting.

But perhaps we can drop support for python 2 on Windows, which would allow us to switch to a newer version of C++. C++17 was officially published a few days ago and C++14 is already fully implemented by the 3 dominant compilers.

What do you think about this? What about the other items on the wish list? Do you know of a use-case where continued avoidance of C++11 is paramount?

ITK 4 intended long-lasting support for compilers, but even compiler authors are abandoning them quickly nowdays. Should we adopt a more flexible and aggressive compiler deprecation?

I think that a change to the fundamental language requirement of a library justifies a major revision increment. So I am of the general opinion that ITK 5 should require C+11.

Additionally to justify the change I’d like to see some good use of it in ITK. Some things that first come to mind:

  • Support move semantics for the core ITK objects
  • Have implementations that make use of C++11 threads
  • Have a FunctorFilter which supports lambda expressions
  • Rvalue support
  • A updated style guideline which requires less typedefs ( auto keyword )

Developing a list that the community can work on may be a good idea?

Adding: Suport for remote module testing against multiple versions of ITK.

I think that’s what wish list is for:
https://itk.org/Wiki/ITK_Release_5/Wish_List

1 Like

Good points @dzenanz, @blowekamp.

Some folks may not be aware, but it is important to keep in mind that ITK can be used with C++11 or higher and ITK does take advantage of newer standard features when available. Considering what VTK ended up with for C++11 adoption, ITK already takes advantage of nullptr, override, delete, default. Interestingly, VTK decided to limit auto application for readability, and it was determined that shared_ptr could not be used or mixed with existing library SmartPointer's.

In terms of what other features come with ITK 5, it will depend on what resources are available and what contributions are made.

Setting aside features, I think a reasonable timeframe to strip out old deprecated code, mark code that is currently as “future deprecated” as “deprecated”, and migrate to new style / replace C++11 macros / update the style guide is the December 2018 at the earliest. We are still working on GitHub migration / finalizing the infrastructure for the June 2018 release.

Given the current state of compilers and operating systems, I think it is reasonable to make the policy in the future that we will support the major compilers for as long as the compilers and operating systems support them. OS’s and compilers are moving on much more quickly these days. And when a new major version of the compiler is released, they usually default to nearly the latest release of the C++ standard. Visual Studio 2017 defaults to C++14, GCC 7 is C++14, Clang 6 is anticipating a move to C++14 or later.

That wish list is the dream! And +1 for moving to modern standards, the more modern the better, but I understand constraints. c++14 is just a small set of upgrades, but generic lambdas sound like a considerable plus for development with generic code.

To reiterate, changing the C++ standard requirement I believe is sufficient justification for changing the major revision of the ITK toolkit. So, moving through the standard would require updating ITK’s major version more frequently. Also even if a compiler defaults to a newer C++ version, it still may support older standards.

Speaking of dropping support for compilers, I believe VS11 2012 ( might might be 2013 ), has outstanding bugs with producing incorrect vectorized code. That compiler in many ways is broken and produces incorrect code (different kind of broken than non-standard following). We should drop support for this compiler which produces erroneous code.

It would be good to update the deprecation macros to include a version where the code will automatically be removed.

One more thing regarding compatibility, last I check the ITK debian packaging was still enabling ITKV3_COMPATIBILITY. It appears this flag may have enable old code to linger longer than needed, and missed that it was intended to aid in active migration.

Yes. However, if there should not be trepidation to update the major version if it largely does not break dependent code.

We have seen similar optimization errors in Visual Studio 2015 and Visual Studio 2017, though.

In general, if the compiler is used, we should support it.

Yes.

However, we should be careful with what commitments we make and not abandon those commitments lightly.

I think the fact that they still have ITKV3_COMPATIBILITY enabled sends the opposite message: If a library is used in applications and is expected to have an impact over a long period of time, it needs to keep supporting those applications build requirements with a significant backwards compatibility effort. Dropping backwards compatibility is not going to cause dependent projects to do the migration – it is more likely to cause them to just drop ITK. Resources to keep up with libraries and dependencies are always quite limited.

Some of their reason for the compatibility flag is that they are supporting old tools that are not being maintained. Perhaps if compatibility isn’t claimed between major releases, vendors may include multiple versions of the toolkit.

Yes.

In practice, Debian struggles with the length of ITK’s build. We should consider stripping down the toolkit into a set of core modules for ITK 5, and put less-used modules into Remote Modules for this reason.

Are they building example and testing? If not, it would take long only on clean rebuilds. ITK’s configure step is one of the longest, if not even THE longest. If I remember correctly, VNL and IOs are taking the lion’s share of compile time and we can’t outsource them to “remote modules”.

FEM framework might be worthwhile to be made remote. Is there any other part which you think is a good candidate?

They need to do a fresh build, and they enable testing (and run the tests). They also try to build for embedded processors, which is even more challenging.

Yes, FEM, some Numerics modules, some Filtering modules, …

Trimming down ITK would be good. There are clearly some less used modules that could be made remote: BioCell, NeuralNetworks , Compatibilityv3?. There are also some filters/modules that are excessively bulking in there compiled size due to mostly being composite filters. Consideration for splitting some modules by new algorithms vs composite filters may be a good idea.

Have they packaged any remote modules yet? I wonder if they are going to have additional requirements.

Being able to compile a remote module against an installed ITK would be nice for this structure.

Even so, we could start preparing for that now: establish timeline, invite community into the early stages of discussion and long-reaching decision-making (e.g. which compilers should be supported, whether to start off with C++14 or C++17 etc), see who is willing to contribute effort to the transition, how much effort and in which areas. And include some of these plans with 4.13 release announcement.

While I would love if we had resources to do a major update/rewrite of ITK to take full advantage of new language features, it does not look realistic right now. So we should plan for a gradual transition. Even just allowing modern code in ITK will improve community participation, as it will be easier and more satisfying to make improvements.

While we don’t need to change the major version number, I don’t mind doing that. And to go along, we should require a much more modern version of CMake with modern C++ ITK. Even if we don’t take full advantage of it right away, having it available will be handy for future enhancements.

1 Like

Yes, and it may even be necessary in practice. For example, it would be required to create the Debian packages. But, it requires some work and possibly backwards incompatible changes.

Yes, definitely.

If the amount of work is low, i.e. C++11, deprecation changes, maybe a style change, we could probably make 4.14 the 5.0 release. Anything more than that is likely 4.15.

There is a major disadvantage to requiring a much more modern version of CMake – people cannot use the version available in package managers. This increases the barrier to development entry significantly. Current stable Linux distributions ship with CMake 2.8.12.

In that case we should definitely go with gradual transition. Since we hardly have resources to do a major rewrite of the build system, we should stick to less costly changes: allowing C++11 and taking some obvious advantages, drop support for older compilers (and hence support for Python 2 on Windows), update style, deprecation iteration, some search&replace cleanup etc.

Since the build system would be mostly intact, I would be fine if we called the new version 4.14 and waited for build system update and perhaps backwards incompatible redefinition of ThreadedGenerateData to increment the major version number to 5.

1 Like

FYI, Interesting C++ survey results:
https://isocpp.org/blog/2018/03/results-summary-cpp-foundation-developer-survey-lite-2018-02

Direct link:

The results for Q8 “What version(s) of C++ are you allowed to use on your current project” appear to support ITK’s move forward from C++03 to C++11 :grinning:

4 Likes

Interesting survey! It’s funny how the word “Package Manager” appears in a lot of those word-clouds.

Hi - I think this thread is as good a place to ask this as a brand new one.

What functionality does itk::SmartPointer provide that std::shared_ptr does not? And linked to this, with C++11 functionality, would it possible to have a ::New() member function that is more similar to std::make_shared and allow forwarding arguments to a constructor, and hence in turn enable a more RAII style?

I don’t envisage for a moment removing all the SetProperty() methods in ITK, but ITK is fairly idiosyncratic C++ for not following the RAII style.

2 Likes

itk::SmartPointer relies in the pointed classes themselves keeping their reference count. std::shared_ptr keeps its own reference count - it is a must when most classes are oblivious to shared pointers.

This choice was made to make it really hard to leak large chunks of memory (i.e. images and friends). And since mechanism was implemented and worked well most classes use it. Rewriting that would be a huge task.

2 Likes