Skip to content
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

Auto-detect std::string_view support by default #642

Merged
merged 5 commits into from
Nov 4, 2024
Merged

Conversation

zeux
Copy link
Owner

@zeux zeux commented Oct 30, 2024

This PR enables std::string_view by default when the compiler supports C++17, and also tries to enable C++17 in a few cases when the compiler should support it. Notably, vcxproj files for VS2019/2022 now enable /std:c++17, and CMake enables C++17 when no specific version is set via CMAKE_CXX_STANDARD; we are now using CMAKE_CXX_STANDARD_REQUIRED=OFF to use CMake's transparent C++ version downgrade.

I originally expected that the next release should go out with string_view being opt-in. However, I'm thinking it might be better to just go all-in:

  1. The release doesn't really have much else outside of a few compatibility fixes. Even if there is a compatibility regression, the only way to find out is to try, and if the release has issues this wouldn't block any other features.
  2. During testing, I encountered a few surprises wrt enabling C++17 support, but zero actual compatibility issues; maybe the worst case here is "std::string_view could be supported but isn't", and risk is reduced.

If this does go in, we'd delay the release; I was originally hoping for a November release, but might push this to January 2025 if this goes through to allow for testing and last minute fixes to go in.

Relates to #626.
Closes #640.

zeux added 4 commits October 30, 2024 10:31
Instead of opting in std::string_view support via PUGIXML_STRING_VIEW
define, always enable it when C++17 is supported; this still requires
enabling C++17 support in the compiler, which this change doesn't
attempt to do yet.
The PUGIXML_STRING_VIEW define is no longer necessary but
_HAS_STRING_VIEW can be enabled manually if the compiler supports it
without advertising C++17 support.
To avoid increasing the build matrix we enable this unconditionally for
VS2019 and VS2022 to be able to test std::string_view. Note that we
already test VS2022 without this flag on GHA so this should catch any
regressions.
This enables std::string_view support for NuGet builds
@zeux zeux force-pushed the string-view-def branch 3 times, most recently from b92d495 to 7ddf099 Compare October 30, 2024 20:16
@zeux zeux marked this pull request as ready for review October 30, 2024 20:17
@zeux
Copy link
Owner Author

zeux commented Oct 30, 2024

Setting CMAKE_CXX_STANDARD is not that great here: the choice propagates to dependent libraries, so this would change behavior for dependent projects that don't specify the standard. I guess ideally we'd enable C++17 for pugixml target without forcing this choice on dependent projects, so they can use std::string_view if they have enabled C++17 themselves. Never mind, this seems to actually work correctly as the variable is scoped to pugixml projects; a dependent project that doesn't specify any versions doesn't get any -std= flags on Linux at least. So maybe this is perfect.

I will leave this PR open until next week; if any CMake experts can chime in and say if this approach is correct, please do.

We only set this when C++ version or requirement flag is not overridden
externally to be able to rely on CMake automatically downgrading the
standard version when the compiler doesn't support it.

CXX_STANDARD 17 also requires CMake 3.8 or later; on earlier versions we
use the old behavior and set C++11.
@mosra
Copy link

mosra commented Nov 3, 2024

(Sorry in advance if this is unhelpful or too tangential.)

What I do in Magnum regarding opt-in C++14/17/20 support (or, opt-in STL support in my case) is that I let the base library be always compiled with some conservative default, and the opt-in functionality is fully inlined in a header (or even tucked away into an extra header if it'd mean pulling in a lot of extra weight). Then, in order to verify that the opt-in functionality actually works, I have dedicated test exectuables that are compiled with appropriate higher standard version.

That way I don't need to worry about accidental ABI breakages, which theoretically shouldn't happen from just switching a C++ standard, but I remember rare cases where attempting to link a library built with C++17 to a C++11 codebase led to issues due to the library using some libstdc++ internals the C++11 build had no idea about. It also makes dealing with packages/installations easier, because even if a distribution builds with an older C++ standard for whatever reason, it doesn't prevent users from actually using the C++17 functionality, if it's all inline.

In the case here it'd mean that the code would inline all operations involving a std::string_view, and they'd delegate to the data + size overloads:

    bool set_value(const char_t* rhs);
    bool set_value(const char_t* rhs, size_t size);
#ifdef PUGIXML_HAS_STRING_VIEW
    bool set_value(string_view_t rhs) {
        return set_value(rhs.data(), rhs.size());
    }
#endif

From my personal experience, given the size of <string_view> itself, the extra inlined methods won't really make compile times any worse. Assuming the compiler inlines at least a bit, for this particular case I think the call overhead would be equivalent to when set_value(string_view_t) was defined in the *.cpp, where it was basically a copy of set_value(const char_t*, size_t). In any case, the major advantage is that you then don't need to worry about enabling C++17 when building the library itself.

@zeux
Copy link
Owner Author

zeux commented Nov 3, 2024

Yeah - I considered this before but this is a further increase in surface area as not all methods with string_view overloads currently have size_t equivalents (in fact most don't), and it would be simpler to keep it that way.

I did check the ABI consequences and it doesn't look like this would break it on any mainstream platforms (Linux/Windows/macOS). I'm also assuming that the distributions will package without overriding the CXX standard, so since it defaults to 17 it should be fine regardless of whether the user requests C++11 or C++17.

@zeux zeux merged commit 3480faa into master Nov 4, 2024
24 checks passed
@zeux zeux deleted the string-view-def branch November 4, 2024 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Automatically enable std::string_view support
2 participants