Skip to content

Provide fallback for missing char8_t support #4736

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

sergiud
Copy link

@sergiud sergiud commented Apr 11, 2025

Clang 11.0.x with libc++ fails to compile tests in C++20 mode due to incomplete char8_t support in std::filesystem::path. Use a specific library feature guard instead of performing a generic C++20 language standard check.

Fixes #4733

  • The changes are described in detail, both the what and why.
  • If applicable, an existing issue is referenced.
  • The Code coverage remained at 100%. A test case for every new line of code.
  • If applicable, the documentation is updated.
  • The source code is amalgamated by running make amalgamate.

Read the Contribution Guidelines for detailed information.

@sergiud sergiud requested a review from nlohmann as a code owner April 11, 2025 19:24
@github-actions github-actions bot added the S label Apr 11, 2025
@sergiud sergiud force-pushed the fs-char8_t-fallback branch from f77af2b to a66c329 Compare April 11, 2025 19:25
@coveralls
Copy link

coveralls commented Apr 11, 2025

Coverage Status

coverage: 99.188%. remained the same
when pulling 3d089b2 on sergiud:fs-char8_t-fallback
into 88c92e6 on nlohmann:develop.

@sergiud sergiud force-pushed the fs-char8_t-fallback branch from a66c329 to 69c3fd0 Compare April 11, 2025 20:27
@github-actions github-actions bot added M and removed S labels Apr 11, 2025
@@ -443,12 +443,8 @@ inline void to_json(BasicJsonType& j, const T& t)
template<typename BasicJsonType>
inline void to_json(BasicJsonType& j, const std_fs::path& p)
{
#ifdef JSON_HAS_CPP_20
const std::u8string s = p.u8string();
const auto& s = p.u8string();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the conditional compilation adds an unnecessary copy to those using it in C++17.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, without this change the tests fail because BasicJsonType::is_string no longer holds in corresponding from_json.

Copy link
Author

@sergiud sergiud Apr 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing against 201811L seems to solve the issue. However, compilation using Clang 11.0.x starts failing again.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sergiud Oh, that's annoying. So, libc++ in Clang 11.0.x sets __cpp_lib_char8_t 201811L but doesn't actually implement p.u8string() returning std::u8string until it's set to 201907L?

That's ugly.

However, this still means that everything using C++17 has to pay for this copy unnecessarily, where they didn't before. Would the following work?

    const auto& s = p.u8string();
#if defined(__cpp_lib_char8_t) && (__cpp_lib_char8_t >= 201907L)
    j = std::string(s.begin(), s.end());
#else
    j = s; // returns std::string in C++17
#endif

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, __cpp_lib_char8_t version is somewhat unreliable. Therefore, instead of feature testing against a specific version for char8_t library support a better approach is probably to provide a std::u8string overload whenever __cpp_lib_char8_t is defined.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable.

@sergiud sergiud force-pushed the fs-char8_t-fallback branch from 69c3fd0 to 161f0de Compare April 11, 2025 21:24
@github-actions github-actions bot added S and removed M labels Apr 11, 2025
@sergiud sergiud force-pushed the fs-char8_t-fallback branch from 161f0de to 8fb2005 Compare April 11, 2025 21:45
@github-actions github-actions bot added M and removed S labels Apr 11, 2025
@nlohmann
Copy link
Owner

Would it make sense to extend the CI to run the Clang tests additionally with -stdlib=libc++?

@sergiud
Copy link
Author

sergiud commented Apr 13, 2025

The ci_test_standards_clang job in the Ubuntu Github workflow seems to be doing exactly that already. The libc++ version used there is likely much more recent and does not expose the regression.

Given GCC 14 (using libstdc++) suffers from a related issue, reproducing the setup for the latter is probably also sensible going forward.

@nlohmann
Copy link
Owner

The ci_test_standards_clang job in the Ubuntu Github workflow seems to be doing exactly that already. The libc++ version used there is likely much more recent and does not expose the regression.

Yes, these jobs use the latest Clang version. Question is if it makes sense to also do this with (some/all) of the other Clang versions we use in ci_test_compilers_clang (3.4 .. 20).

Given GCC 14 (using libstdc++) suffers from a related issue, reproducing the setup for the latter is probably also sensible going forward.

Not sure what additional setup is used there. We already use GCC 14 in the CI. Maybe @jelly can help?

@sergiud sergiud force-pushed the fs-char8_t-fallback branch from 8fb2005 to 68a0a01 Compare April 13, 2025 15:12
@sergiud
Copy link
Author

sergiud commented Apr 13, 2025

According to #4733 (comment) it's -fno-char8_t.

@sergiud sergiud force-pushed the fs-char8_t-fallback branch from 68a0a01 to 955d205 Compare April 13, 2025 15:19
Copy link

🔴 Amalgamation check failed! 🔴

The source code has not been amalgamated. @sergiud
Please read and follow the Contribution Guidelines.

@sergiud sergiud force-pushed the fs-char8_t-fallback branch from 955d205 to 19687e7 Compare April 13, 2025 22:12
@github-actions github-actions bot added the tests label Apr 13, 2025
@nlohmann nlohmann added this to the Release 3.12.1 milestone Apr 14, 2025
@nlohmann nlohmann requested a review from gregmarr April 15, 2025 12:10
@sergiud sergiud force-pushed the fs-char8_t-fallback branch 2 times, most recently from c26c38a to 1d11ec1 Compare April 15, 2025 20:09
Clang 11.0.x with libc++ fails to compile tests in C++20 mode due to
incomplete char8_t support in std::filesystem::path.

Signed-off-by: Sergiu Deitsch <[email protected]>
@sergiud sergiud force-pushed the fs-char8_t-fallback branch from 1d11ec1 to 6c4cf7a Compare April 17, 2025 08:37
Copy link

🔴 Amalgamation check failed! 🔴

The source code has not been amalgamated. @sergiud
Please read and follow the Contribution Guidelines.

@sergiud sergiud force-pushed the fs-char8_t-fallback branch 2 times, most recently from 4b8310c to 3d089b2 Compare April 17, 2025 10:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Clang 11.0.x compilation error
4 participants