Skip to content

[SUGGESTION] Use std::format for string formatting if possible #133

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

Closed
switch-blade-stuff opened this issue Nov 22, 2022 · 8 comments
Closed

Comments

@switch-blade-stuff
Copy link

Since we have std::format as part of STL now since C++20, I would expect people to be implementing specializations for std::formatter in Cpp1. As such, in my opinion it would be beneficial to use std::format for to-string conversion (or string formatting itself) if possible.

It would avoid the need to duplicate string conversion code (only a specialization of std::formatter will be needed), and could improve performance, since std::format is more efficient than string concat. It would also prevent creation of yet another string formatting standard.

@switch-blade-stuff
Copy link
Author

Missclick, terribly sorry.

With char8_t, char16_t, char32_t the solution could be to either use the to_string and string concat approach, or use std::format and string conversion. The second approach would be more universal, however involves locales. Personally, it seems like an acceptable compromise, since the use of char8_t, char16_t and char32_t for string literals and other general-purpose string operations is limited at best due to usability and compatibility issues (char8_t is addressed with C++23), as such string conversion would not have a big impact.

@hsutter
Copy link
Owner

hsutter commented Dec 16, 2022

I like this suggestion and I'm all for using the best standard facilities and requiring C++20 as a baseline... but this means the reality of "C++20 as she is spoke," meaning the (large) subset of C++20 that is implemented and supported in at least the three major compilers.

As a quick test to see how <format> was doing, I tried pasting cppreference's short <format> example and as of this writing only 2 of 3 major implementations can handle it... Godbolt with GCC/Clang/MSVC "trunk/latest": https://godbolt.org/z/sxhMc4sPW

So I'm interested in using <format> but I can't take a hard dependency on it yet, because I'll generate code that won't work on libc++. Does that make sense?


That said, this leads to a good question: What level of C++ support should cppfront take a hard dependency on? Informally I've been targeting the following, because I want Cpp2 code to be compilable with at least the latest version of the three major C++ compilers:

all of C++20 supported by the current released versions of MSVC, GCC, and Clang

But perhaps I should raise the bar a little because not everyone can pick up the very latest version right away... maybe it should be

all of C++20 supported by the current and previous major versions of MSVC, GCC, and Clang

Taking <format> as an example: For Clang, given Clang's 6-month spring/fall release cycle, this would mean waiting at least until fall 2023 to take a dependency (if <format> is added in spring 2023 in Clang 16, then waiting until fall 2023's Clang 17 would satisfy 'current and major previous' version requirement).

And, well, now that we're using that example, this also means ignoring Apple Clang, which I've heard tends to lag and not always take all trunk features. Apple Clang is kind of important though, because Mac/iOS devs are a significant audience, so maybe it should be this to acknowledge that there are in practice two Clangs?

all of C++20 supported by the current and previous major versions of MSVC, GCC, Clang, and Apple Clang

... but honestly I don't know how to evaluate that because I have a hard time finding the delta between Apple Clang and Clang, and IIUC you need to have a Mac to test with it (e.g., I don't see it on Godbolt).

@hsutter hsutter closed this as completed Dec 16, 2022
@filipsajdak
Copy link
Contributor

As I am a Mac user, I can help in evaluating that.

@JohelEGP
Copy link
Contributor

GCC's current release, GCC 12, doesn't support <format>. Clang does, since Clang 14, as noted at https://en.cppreference.com/w/cpp/compiler_support:

The paper is implemented but still marked as an incomplete feature. Not yet implemented LWG-issues will cause API and ABI breakage.
Prior to libc++ 15, support is disabled by default and can be enabled with -DLIBCXX_ENABLE_INCOMPLETE_FEATURES=ON when building LLVM.
In libc++ 15 and later, this feature can be enabled with the -fexperimental-library compiler flag when using libc++ (see https://libcxx.llvm.org/UsingLibcxx.html#enabling-experimental-c-library-features)
1671150659
1671150672

@switch-blade-stuff
Copy link
Author

switch-blade-stuff commented Dec 16, 2022

That said, this leads to a good question: What level of C++ support should cppfront take a hard dependency on?

IMHO, since Cpp2 is still an experiment as of now, and as such no production code is expected to be written with it, we should not really worry about the minimal dependencies. By the time (and if) Cpp2 will be ready enough to be used in production, I would expect that the major compilers will support all facets of C++20.

We already support C++20 modules, even though modules are not implemented by all compilers (as of current release versions).

Finally, if we want to encourage idiomatic use of C++, we should be utilizing all utilities provided by STL, instead of inventing a competing standard.

We could, for example, conditionally enable string interpolation only if <format> is available.

Additionally, projects that cannot upgrade to the latest-and-greatest version of GCC, Clang or MSVC probably would not be using Cpp2 either.

@hsutter
Copy link
Owner

hsutter commented Dec 19, 2022

@switch-blade-stuff

conditionally enable string interpolation only if <format> is available.

I understand, but I'm going to avoid conditionally supported features for now. Even for -p, which relies on modules, I go to some trouble in cpp2util.h to "make it work" on modern nearly-C++20 compilers that don't have modules yet.

@filipsajdak

As I am a Mac user, I can help in evaluating that.

Thanks! Perhaps the simplest would be to create another sister results directory beside /clang-12 (perhaps /apple-clang-##) which would just need one shell script similar to the one in /clang-12 to pull down the .cpp files in the parent and build/run them using Apple Clang.

If you'd like to do that, please just create a PR and I'd be happy to merge it.

I would not be able to test with that directory or update it, so periodically if you could let me know if anything broke there that didn't break in the other ones that would be great.

Actually that would also help fill another gap: I don't currently have checked in a test with Clang using libc++ (the current /clang-12 uses libstdc++), and presumably your Apple Clang environment would use libstdc++.

Thanks!

@jcanizales
Copy link

I think this depends on a more important question about your plan.

Will CppFront stay a transpiler from new syntax to existing C++? How will things like metaclasses and compile-time blocks with code injection be translated? By waiting until the major compilers implement it first in standard C++ syntax?

Because if so, I think this project would benefit from just using whichever compiler is most advanced at any given point.

Unless you've thought it through and found a way to implement those features using current C++ syntax? (After all, macros + templates are Turing complete at compile time - so there's bound to be a possible implementation).

@hsutter
Copy link
Owner

hsutter commented Dec 22, 2022

How will things like metaclasses and compile-time blocks with code injection be translated?

I plan to implement those in cppfront via support for inspecting and changing the parse tree.

By waiting until the major compilers implement it first in standard C++ syntax?

No, in part because one goal of cppfront is to implement proposals for ISO C++ in a simpler syntax and compiler. For example, in cppfront I've already implemented inspect, is, as, guaranteed definite initialization, move from last use, forward from last use, and similar things.

macros + templates are Turing complete

We don't have to resort to that (mostly)... :) there are a few macros in cpp2util.h, but there's a lot more if constexpr and requires { } magick. Those are the workhorse features without which cppfront would have a much harder time translating new advanced features like inspect into Cpp1 code, and I probably wouldn't have tried creating cppfront without being able to target them. In contrast, <format> is a nice-to-have where whether it's there or not doesn't make much difference in cppfront implementation feasibility/difficulty and so I prefer to choose to optimize for "reach" (broader compiler support) first and provide workarounds until features like <format> and import std; become reliably available.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants