Json: Compilation Error on Clang 5.0 Upgrade

Created on 10 Sep 2017  路  25Comments  路  Source: nlohmann/json

Upgrading to Clang++-5.0 on Travis-CI Trusty is producing the following error:

json/src/json.hpp:9869:66: error:  no type named 'string_view' in namespace 'std'
  ...and not std::is_same<ValueType, typename std::string_view>::value

Also tested on Ubuntu 16.04 Clang++-5.0 standalone without the rest of the project and still failing with the same error. g++ working fine on both systems.

wontfix

Most helpful comment

One workaround (though quite brittle), would be:

// FixedJson.hpp (your header)
#include <experimental/string_view>
#include <json.hpp>

Then you include this file instead of including json.hpp directly. Of course once your distribution ships a library with C++17 support, you will not need that workaround anymore.

All 25 comments

Which library version are you using?

This is only happening on the develop branch-- release 2.1.1 works fine.
using libstdc++ 5.4.1

Strange. I'm using clang version 5.0.0-svn312333-1~exp1 (branches/release_50) on Travis (see https://travis-ci.org/nlohmann/json/jobs/273804833 and https://travis-ci.org/nlohmann/json/jobs/273804832) without problems.

Seems related to #586 and #464. Do you use the latest develop version?

Yup, I'm at fcba9ec537efa44d19bd53933e2f06ab11affdf1.

I'm using the same version of clang with the -std=c++17 flag.

Could you please try to include <string_view>?

<string_view>doesn't work, included <experimental/string_view> and it compiles perfectly!

Alright. Then there is something incomplete in a SFINAE. I don't want to include string_view - I just want to make sure I don't try to convert to/from it. I see if I find a way and may come back to you to test it since I cannot reproduce the error myself.

I still cannot reproduce the issue. It seems that the SFINAE in

#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_MSC_VER) && _MSC_VER >1900 && defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
                   and not std::is_same<ValueType, typename std::string_view>::value
#endif

needs to "know" std::string_view, and this fails without including experimental/string_view. When I run clang 5.0, __cplusplus is defined to 201703L and the above code works without including any header for string_view.

You are probably seeing differences in the STL about which headers are included by other headers, or which classes are forward declared. The official position of the committee is that you MUST include all headers for classes that you use. To do otherwise is to risk compile breaks when you change compilers, or even versions.

This would mean we need to include the required headers for std::string_view to exclude it via SFINAE, right?

you might be able to use SFINAE to check for the existence of it first, but then you might run into ODR issues if some TUs know about it before including json.hpp and others don't.
.

In GCC 7.2.0, <string> includes bits/basic_string.h which contains

#if __cplusplus > 201402L
# include <string_view>
#endif

In Clang 5.0.0, <string> contains

#include <string_view>

I do not understand why @ErikPartridge 's Clang does not know about std::string_view (as json.hpp includes <string>). What am I missing?

For me with clang++:


$ clang++ --version
clang version 6.0.0-svn315197-1~exp1 (trunk)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin


The header is in #include
and string_view is under std::experimental::string_view

@xirius Thanks! Can you compile the library's tests with your clang version or do you experience the same error?

It compiles.


mkdir build
cd build
cmake -DCMAKE_CXX_COMPILER=/usr/bin/clang++ ..

-- The CXX compiler identification is Clang 6.0.0
-- Check for working CXX compiler: /usr/bin/clang++
-- Check for working CXX compiler: /usr/bin/clang++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /mnt/dev/json/build

cmake --build .
...
ctest
...
100% tests passed, 0 tests failed out of 70

Label Time Summary:
all = 186.48 sec (35 tests)
default = 8.70 sec (35 tests)

Total Test time (real) = 195.22 sec

@ErikPartridge What confuses me is that your Clang 5 relies on <experimental/string_view>. Shouldn't <string_view> be supported?

Well, clang is a compiler and string_view is part of the standard library. So installing clang 5 (or 6 dev branch) doesn't bring the c++17 headers/lib(std)c++ (well at least not on Ubuntu/Debian and the like).

Well, it is hard to support a compiler without C++17 headers, but with the -std=c++17 flag.

Could we use the __has_include feature to detect that?

That may work. Then I would need to check for <string_view> and <experimental/string_view>.

Related: #795

I am still not sure whether this should be fixed. I mean: why should this library include <experimental/string_view> just to rule out errors in this combination of a C++17 compiler without a C++17 standard library?

In principle, I agree. In practice, I'm one of the affected because the clang distribution and repos don't include libc++ and I haven't gotten around to building my own. It would be nice if I didn't have to.

One workaround (though quite brittle), would be:

// FixedJson.hpp (your header)
#include <experimental/string_view>
#include <json.hpp>

Then you include this file instead of including json.hpp directly. Of course once your distribution ships a library with C++17 support, you will not need that workaround anymore.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

afowles picture afowles  路  3Comments

MariaRamos89 picture MariaRamos89  路  4Comments

jmlemetayer picture jmlemetayer  路  3Comments

moneroexamples picture moneroexamples  路  4Comments

mlund picture mlund  路  4Comments