Survey about updating VTK's minimal C++ standard version

Hello VTK community!

VTK is a widely used library for visualization. As such, it has needed to support many different compilers, including gcc 4.8.5. As a result, VTK has been limited to using only features available in the C++11 standard.

We have heard from the institutions that previously needed gcc 4.8.5 support that they have moved to more recent gcc versions (greater than 8). At the same time, there is a lot of interest among VTK developers to move to a more recent standard, such as C++17. This opens the possibility of updating our C++ version in upcoming versions of VTK.

Before we do that, though, we would like to hear from you about the minimal compiler versions you need to use to compile VTK. What’s the oldest compiler you need to support, and if you know it, which version of C++ does it support.

Please let us know in the comments below.

Thanks!
Cory

7 Likes

All of the applications I work with/on can be built with gcc 13 and clang 15, but I do work on a highly limited subset.

Does moving towards a new C++ version entail incorporating new standard features into the core vtk data model? Curious what the goals of moving to C++17 are :slight_smile:

Hi Cory,

We build VTK with Visual Studio 2019, it seems that it does support C++17, although there might be some defects (not an expert in the area though). But thanks for asking for the input and good luck with the development!

Ugis

A move to C++17 would be welcome. ITK has already switched. Here are the corresponding compiler versions:

1 Like

For over a year, the oldest HPC I use default to at least GCC 8.x

Does moving towards a new C++ version entail incorporating new standard features into the core vtk data model? Curious what the goals of moving to C++17 are

string_view, optional, filesystem are few things that can make developing new code in VTK fun. I’d like to use designated initializers from C++20. It makes implementation code descriptive and clean.

Random example:

struct TimerPayload
{
  int Timeout;
  bool Repeat;
  std::string Source;
};
TimerPayload payload{.Timeout=1000, .Repeat=false, .Source=__func__};
this->InvokeEvent(vtkCommand::StartEvent, &payload);

Of course, with c++20, we’d get a lot more than just designated initializers :slight_smile:

Visual Studio 2017 supports C++17 compilation from version 3.5 onwards. The last update was version 4.8

Learned that C++17 supports If statement with initializer. I think it’s useful when dealing with iterators in VTK.

There are instances of code in VTK that assign and check the value in the argument of if to prevent accidentally dereferencing a null pointer and/or limiting the scope of a resource.

Example:

This is safer

if (auto gradients = pointData->GetArray("Gradients"))
{
  // print gradients
  auto r = vtk::DataArrayValueRange(gradients);
  std::copy(r.begin(), r.end(), std::ostream_iterator<double>(std::cout, '\n'));
}
// gradients variable cannot be accessed anymore.

instead of writing

auto gradients = pointData->GetArray("Gradients");
if (gradients != nullptr)
{
  // print gradients
  auto r = vtk::DataArrayValueRange(gradients);
  std::copy(r.begin(), r.end(), std::ostream_iterator<double>(std::cout, '\n'));
}
// gradients is nullptr, but the variable is still accessible!

As useful as that is, it’s not possible to do that with iterators. Right now, this, by itself, will fail to compile.

if (((auto iter = entries.find(key)) != entries.end))
{
  std::cout << iter->first << ':' <<  iter->second << std::endl;
}

leading one to write unsafe code

auto iter = entries.find(key);
if (auto iter = entries.find(key))
{
  std::cout << iter->first << ':' <<  iter->second << std::endl;
}
// compiler doesn't complain when iter is accidentally dereferenced, crashes at run time.
int a = iter->first;

With if-initialization statements in C++17, that can be re-written safely.

if (auto iter = entries.find(key); iter != entries.end())
{
  std::cout << iter->first << ':' <<  iter->second << std::endl;
}
// iter is inaccessible. compiler will complain if iter is dereferenced.
2 Likes

Can we please collect these things into issues; ideally an overarching issue for C++17 usage with individual issues for each pattern to adopt. If possible, ways to identify these patterns for migration would be ideal.

I don’t know if a C++ version exists, but coccinelle allows crafting “semantic patches” that perform code transformations. Maybe it could be hacked up enough for C++ usage by treating :: as part of identifiers?

3 Likes

Having heard no objections to updating VTK to require C++17, shall we proceed with making that change?

I think we can; let’s bump CMake to do C++17. This probably involves some new warnings, so the MR might be larger. Documentation about minimum compilers needs updated too. mindeps might need a new devtoolset installed too.

Note that clang-format is currently set to using Cpp11. Updating that may involve some reformatting; we should try this without updating clang-format first; if we need to update, it’s a bit more involved (but hopefully doesn’t change too much to inhibit nice backporting; the main reason pre-branch formatting is vastly preferred).

2 Likes

I have no issues wrt the VTK Examples, as some examples already use C++17. So it’s a yes from me.

This seems like a good idea.

I think the reason for the old GCC 4.8.5 requirement was RHEL 7 and it’s derivatives (Centos, …) have lived for a long time being very successful and stable using that compiler. However, official support for RHEL 7 ending in June this year will finally put the last nail in the coffin for any serious system still using these legacy operating systems, so the switch to a different and more modern distro have mostly already happened.

“EL-8” (RH, Rocky, Alma, Oracle, Centos Stream, …) based distros is a different era w.r.t. code development and tooling… As a developer myself I’m so glad I don’t have to deal with RHEL-7 any more!

So please get rid of the old stuff!