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

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.
3 Likes