Visual Studio 2017 with C++17 and Boost

By , last updated September 29, 2019

Visual Studio 2017 was just recently updated to version 15.5. It brings many goodies for us C++ programmers, among them a C++17 compiler switch /std:c++17, and a conformance mode switch /permissive-.

Those two switches have been available since 15.3, but with the 15.5 update they are available in the GUI as switches. They are avilable through the C/C++ -> Language tab.

Two new switches in VC 15.5

Two new switches in VC 15.5

But be warned though. Those two switches will probably break existing code, as they should.

Two-phase name lookup

/permissive- enables two-phase name lookup in the C++ compiler. It is still work in progress, and doesn’t currently work with OpenMP or C++/CLR modes.

Two phase lookup is for templates, and defines in no uncertain terms what method calls inside the template should and could call. An excellent write-up by the Visual C++ team explains what two-phase name lookup is in detail.

C++17

The compiler switch /std:c++17 enables C++17 mode. With 15.5, many C++17 features have been implemented. There are only a few features missing. See the table at CPP Reference for an up to date listing of compiler support.

std::byte ambiguous symbol and rpcndr.h

There is actually a conflict between C++17 and one Windows header.

The precursor is that using namespace std; is used before #include <Windows.h>, and there will be a conflict in the ancient header rpcndr.h about the definition of a byte.

1>c:\program files (x86)\windows kits\10\include\10.0.16299.0\shared\rpcndr.h(192): error C2872: 'byte': ambiguous symbol

std::byte is a new type in C++17, and different than the usual definition of a byte. CPP Reference has more detailed information about std::byte. In the ancient header, a byte is defined as typedef unsigned char byte;. This conflicts with the C++17 definition of a byte, being enum class byte : unsigned char { };.

For Visual Studio, this behavior can be turned off by defining the preprocessor value _HAS_STD_BYTE to 0.

Boost 1.65 and 1.66

Boost 1.66 was released on December the 18th 2017.

Building Boost 1.66 is almost identical to building 1.64 or 1.65 versions.

Most issues with Visual Studio 2017 Update 5 and Boost are present in both 1.65 and 1.66.

Unknown compiler / too new compiler

Both 1.65 and 1.66 will complain with the 15.5 compiler.

Boost 1.65 Compiler Warning

Unless treated, 1.65 will complain about the compiler version.

Unknown compiler version - please run the configure tests and report the results

The file boost_1_65_1\boost\config\compiler\visualc.hpp must be manually edited at line 330.

Change 1911 to 1912 so the line reads:

#if (_MSC_VER > 1912)

This will silence the above warning.

Boost 1.66 Compiler Warning

With 1.66 there is one additional method of silencing the warning, which also has been changed. In addition to the fix for 1.65, defining BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE will silence the warning.

Info: Boost.Config is older than your compiler version - probably nothing bad will happen - but you may wish to look for an update Boost version.  Define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE to suppress this message.

This is a good change. From 1.66 there is no need to edit the file, check in the change, and hope all other developers do the same. Just define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE in a properties file or in C/C++ -> Preprocessor and be done with it.

Boost and C++17

The C++17 standard removed some features from the language. Some libraries in Boost rely on some removed features.

Of those I’ve encountered, both could be silenced with preprocessor defines.

Inheriting from std::iterator

Deriving from std::iterator is deprecated and will result in a compiler error with default settings in 15.5.

This simple program, built with C++17, will trigger the error below:

#include <boost/iterator.hpp>

int main(){}

Gives the error:

error C4996: 'std::iterator': warning STL4015: The std::iterator class template (used as a base class to provide typedefs) is deprecated in C++17. (The <iterator> header is NOT deprecated.) The C++ Standard has never required user-defined iterators to derive from std::iterator. To fix this warning, stop deriving from std::iterator and start providing publicly accessible typedefs named iterator_category, value_type, difference_type, pointer, and reference. Note that value_type is required to be non-const, even for constant iterators. You can define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.

Use the following preprocessor define to disable just this warning / error.

_SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING

auto_ptr

auto_ptr has been removed from C++17 after being deprecated for years.

There are still a couple of libraries in Boost 1.66, which still uses auto_ptr. The error will look something like this: error C2039: 'auto_ptr': is not a member of 'std'.

auto_ptr can be enabled again by defining _HAS_AUTO_PTR_ETC to 1.

#define BOOST_CONFIG_SUPPRESS_OUTDATED_MESSAGE
#define _HAS_AUTO_PTR_ETC 1
#include <boost/locale.hpp>
int main(){}

This little program will build without warnings on /W4.