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

Add C++ 20 #113

Open
barnasm opened this issue Mar 24, 2021 · 35 comments
Open

Add C++ 20 #113

barnasm opened this issue Mar 24, 2021 · 35 comments

Comments

@barnasm
Copy link

barnasm commented Mar 24, 2021

Please complete the following information:


👍 reaction might help to get this request prioritized.

@barnasm barnasm changed the title Add [language] [version] Add C++ 20 Mar 24, 2021
@Urfoex
Copy link

Urfoex commented Mar 25, 2021

Probably still needs some time to mature.
From ~ half a year ago, the support of version 20 features in compilers is still lacking a bit…
#42 (comment)

Out of curiosity:
Which features are you looking for?

@barnasm
Copy link
Author

barnasm commented Mar 25, 2021

Some of the new features in std may help us write more compact code that is easier to read. for example std :: ranges, std :: to_array, std :: span, std :: map :: contains, std :: vector :: erase etc. Maybe that doesn't seem like a big deal, but I'd like to practice, learn and take advantages of the latest available standards.

So I will ask the opposite question. Which lack of compiler functionality prevents us from adding C ++ 20 support?

@Urfoex
Copy link

Urfoex commented Mar 25, 2021

Ranges can at least be used somewhat with ranges-v3 library:
#42

Yeah, such neat methods would be nice.
Doing latest C++ version, and then coming to some prior version, complaining that some things are not there, is always a little confusing. In such cases I just copy-paste the fitting old code.

Personally I would like to see the following still missing features:

  • coroutines
  • concepts
  • modules
  • ranges (usable via ranges-v3)
  • text formatting (usable via fmt Add {fmt} for C++ #87)

But then again, for solving problems, they are not that much needed.

Also, currently Clang is used for compiling: #42 (comment)
With MSVC or GCC there would already be a bit more support.

All in all, definitively +1 for new version ^^

@kazk
Copy link
Member

kazk commented Mar 25, 2021

Which lack of compiler functionality prevents us from adding C ++ 20 support?

Technically, nothing prevents adding support (maybe the test framework need another patch, but haven't tried yet). I just don't want users to get confused and complain (e.g., "X is in C++20, but doesn't work on Codewars"). Unlike most of the languages with versions that describes the implementation, C++20 is a standard and compilers are still working on it. We show compiler name and version, but users won't look up the compiler support status.

That being said, we can add support sometime soon if C++ users think it's ready.

With MSVC or GCC there would already be a bit more support.

We can use GCC if necessary. I think Clang was chosen because of the better error messages many years ago. As far as I know, GCC got much better.

/cc @error256 @hobovsky

@wrazik
Copy link

wrazik commented Apr 27, 2021

Any update here?

As the compiler version is known, users can check support for a specific feature. C++ people are aware that C++20 is not fully supported in gcc & clang (MSVS is already feature-complete!)

C++20 changes significantly way of writing the code - concepts, ranges, coroutines. Algorithms will look totally different. C++20 is a must-have!

As already mentioned, it would be great to have ranges-v3 & fmtlib also available.

@kazk
Copy link
Member

kazk commented Apr 27, 2021

Any update here?

I'm waiting for feedback.

As already mentioned, it would be great to have ranges-v3 & fmtlib also available.

fmt and ranges-v3 are already supported.

@wrazik
Copy link

wrazik commented Apr 27, 2021

What feedback do you need? There is never too soon to upgrade the compiler :) Compiler support for C++20 features is available here: https://en.cppreference.com/w/cpp/compiler_support/20 . Gcc has better support for ranges so I would vote for switching to gcc. There is no significant difference in error readability nowadays.

I don't think you should wait till all features will be implemented. Missing stuff is rather minor, all game-changers (modules, ranges, concepts, couroutines) are there.

@hobovsky
Copy link

I am sorry, but I missed the notification that you mentioned me.

Unfortunately, as you probably noticed, my C++ skills are really rusty (I stopped doing professional C++ a couple of weeks before C++11 got published) and I am completely out of the loop when it comes to compilers, support matrices, most of modern features (modern as in C++11 and newer ;) ) so I have no strong opinion on whether C++20 is good to go or not.

The one thing I know I like about C++20 is formatting, improvements to containers (contains, yay!), and concepts (if I only wrap my mind around how to use them). However I'd definitely vote for C++20 if it'd mean anything better than Igloo ;)

There are two new members who are very active in area of C++ authoring, I could bring this topic to their attention and see what others think :)

@wrazik
Copy link

wrazik commented Apr 27, 2021

The difference between C++17 and C++20 is bigger than the difference between C++03 and C++11. It will really make a difference.

@wtlgo
Copy link

wtlgo commented Apr 27, 2021

Hello, In my opinion, it would be better to wait a little bit more till compilers fully support C++20, but the current coverage by the most popular compilers is pretty enough to be useful. Though, I wouldn't for example use it in my personal projects yet.

@mere-human
Copy link

This issue is still relevant.
Now Clang has support for most of the C++20 features.
Using C++20 will allow to write more compact code using the best practices.
Switching from C++17 to C++20 we will not lose anything. The same C++17 code is still valid.
Clang C++20 status:
https://clang.llvm.org/cxx_status.html#cxx20
https://libcxx.llvm.org/Status/Cxx20.html

@kazk kazk moved this to Next Up in Code Runner Jul 15, 2022
@kazk kazk added this to Code Runner Jul 15, 2022
@Hariom-Algo
Copy link

Any update ?

@FilipPlotnicki
Copy link

FilipPlotnicki commented Mar 9, 2023

The ability to use c++20 features would be really helpful

@ozz-life
Copy link

New Year 2024 is coming soon...

@bernb
Copy link

bernb commented Oct 6, 2023

Being restricted to C++17 makes it hard to use codewars to improve my C++ skills. I want to train good practice of today and the forseeable future, not good practice of 5 years ago that's already deprecated when it comes idiomatic C++.

@Waldisss
Copy link

Waldisss commented Jan 5, 2024

When will C++20 be added?

@kazk
Copy link
Member

kazk commented Jan 5, 2024

I'm hoping sometime soon. I started looking into adding C++20 support before the end of the year. Testing with Igloo seems to be working, at least for the very basic tests, but I'm hesitating to continue using it with so many known issues.

Qualified doesn't use Igloo, so code runner currently supports GoogleTest and Criterion for C++ as well. I haven't been able to make these work with C++20 yet.

  • GoogleTest v1.14.0 should support C++20, but I'm getting many warnings for some reason.
  • Criterion must be updated to v2.4 to support C++20, but there are breaking changes affecting us preventing the update (Update Criterion to 2.4 #193 (comment)).

Catch2 mentioned in #52 is very nice and lightweight, so that's an option too.

Obviously, changing the test framework means all the existing kata must be updated manually, so this is not an easy decision to make.

What do you guys think?

@hobovsky
Copy link

hobovsky commented Jan 5, 2024

Obviously, changing the test framework means all the existing kata must be updated manually, so this is not an easy decision to make.

Step 1: Create a 1 dan task for a script to migrate kata from one format to another.
Step 2: Create a collectible badge for a user who converts most kata manually.
Step 3: Wait.

Even better incentive could be making the obsolete C++ translations untrainable, and encourage the community members to fill the void.

Okay, but seriously now: I have never used neither Catch2 nor GoogleTest, so I have no preference. Heck, since custom assertion messages have been added to Snowhouse, the framework is at least bearable. However, what I would really like to get from the update of C++ setup is having snippets as separate translation units, or, ideally, possibility to represent solution snippet and preloaded as a pair of header file + implementation file.

Ad amount of kata and backwards compatibility: there's ~1200 C++ kata which would require an update. A lot, but still fewer (by a lot) than amount of kata which require(d) update for JS or Python. I know that update of C++ code would be more complex than JS or Python, but I would estimate the amount of effort as similar, and not much higher. Great effect would be that redoing C++ translations would hopefully help to get rid of really, really many terrible setups and designs: remove terrible requirements for rounding, strict float equality assertions, fix functions with bad or non-idiomatic signatures, adding random tests, improving structure of test cases, adding feedback for failing tests...

@kazk
Copy link
Member

kazk commented Jan 5, 2024

Yeah, we're doing that with GoogleTest. Qualified allows users to create files in the project directory, but also supports the minimal format like Codewars. In that mode, we create include/challenge.h from preloaded, src/solution.cpp from solution, and tests/test_solution.cpp from tests. {src,tests}/CMakeLists.txt are dynamically generated based on the list of input files. The tests have the target lib (src/) linked and uses header files in indlude/.

If we're making the setup incompatible, there's no reason to keep using Igloo.

@kazk
Copy link
Member

kazk commented Jan 19, 2024

Created https://github.com/codewars/next-cpp to show how the next C++ version may be supported, and to experiment publicly. I haven't had the chance to document it well, but I hope it's clear enough.

  • gtest/ is basically what I described above using GoogleTest
  • catch2/ is same the setup with Catch2 instead of GoogleTest
    • The custom reporter is unfinished because the test events were emitted unexpectedly, and I ran out of time.
  • We can also try using Igloo similarly
    • Can we avoid many of the known issues with a better setup?
    • To do this, we need to first update https://github.com/codewars/igloo to support CMake's FetchContent that's used to manage dependencies

I didn't create container images, but you should be able to play with them if you have newish C++ compiler, CMake and Ninja. I'll accept PRs for Dockefiles. Feel free to contribute in any way.

Some feedback/help I'm looking for:

  • Other than the test framework choice, what do you think of the setup?
    • Can you think of any kata that's impossible/super difficult to update?
    • How is preloaded section used typically on Codewars? Will the new setup prevent this usage?
  • What do you think of GoogleTest syntax/capability?
  • Try updating some of the more complex kata to find any possible issues
    • Don't we have some kata with custom stringifier?
  • Implement the custom reporter for Catch2
  • Add a similar setup using Igloo under igloo/
  • Any other suggestions/contributions to https://github.com/codewars/next-cpp
    • Different approach
    • Dockerfile
    • Add/clarify READMEs
    • Better, more realistic test examples (I took them from gtest/Catch2 docs)
  • Ask other users interested in new C++ for feedback

@hobovsky
Copy link

hobovsky commented Jan 19, 2024

Don't we have some kata with custom stringifier?

I do not think you need to worry about these. Currently, in Snowhouse-based kata, the custom stringizers are used for one of two reasons: stringification of types not supported by default stringifier in assertion messages, and accuracy of floats in failure messages. The code of the stringifier is not referenced directly by any code of kata, so it can be removed and snippets will continue to compile (only messages will change at runtime). I expect the new framework to have some other way of solving the problem of presentation of data in texts (titles, messages, logs, whatever).

One potential problem can be direct calls to Stringizer<T>::stringify(T data) by some tests as a "lazy" way to stringify vectors, but these should not be many, and should be easy to fix by replacing with fmt or manual implementation.


I can try to set up GTest and Catch2 in my local VS and translate some kata and see how it goes. I do not know what kata can be especially tricky, except a couple of template metaprogramming ones ("factorial in compile time" etc), or macros, because they require the solution to be put in a header file - what might look awkward if challenge.h would be created from Preloaded, and what would make the preloaded, well, a solution :) Additionally, preloaded snippet cannot be edited while solving, so there is no way for users to write a part of a solution in the challenge.h. I do not know what kata use any complex setup, but if you could provide some info like:

  • what C++ kata has a Preloaded snippet (except stringizer),
  • what kata contains template keyword or #define preprocessor directive in solution or in preloaded (except Stringizer),

then I could take a look.


To be honest I do not really see a good way to fit the C++ compilation model into the 3 snippets we have now. I think that repurposing preloaded will not prove to work well, and that ideal solution would be to introduce two more tabs (for solution.h visible to authors and users, and preloaded.h editable only by authors), or employ some runner-side preprocessing and use markers in submitted code snippets like:

//CW SOLUTION_H
... declaraitions, templates which are a part of solution

//CW SOLUTION_CPP
... definitions, private solution stuff

The markers and preprocessing could be potentially backed by the #line X some_filename directive. I know that preprocessing in the runner is not a great thing, but since a solution to a vast majority of kata is a single function which can be re-declared in tests, such markers could be made optional and used only for kata which find them necessary.

@hobovsky
Copy link

FYI codewars/next-cpp#1

@armeanco
Copy link

By updating the Kata we pursue the functionality indistinguishability? If so, I can't imagine particularly impossible one, but I can imagine the ones for which it would require time to make it proper. I personally think that it doesn't matter if we switch from the recent test framework to a newer one (despite the Authors/Translators who prefer to keep it as it is for some reasons).

@kazk
Copy link
Member

kazk commented Jan 19, 2024

  • what C++ kata has a Preloaded snippet (except stringizer)

See https://gist.github.com/kazk/3732ef1b693a3c4483a0b8e75f0b524a for a list with a basic summary for each. There are some kata with only #include and/or using std;.

image


Kata with #define in preloaded:

  1. Expression Transpiler
    #define require(e) if (!(e)) return 0
  2. Image Processing
    #define C(e) static_cast<char> (e)
  3. Parenthesis detector
    #define RealAssert Assert
    #define RealFailure Failure
  4. Parenthesis detector++
    #define EpicFail42 Assert::Failure

Kata with #undef in preloaded:

  1. Versions manager
    // this prevents weird collisions with the standard library macros
    #undef major
    #undef minor

Kata with template in preloaded were all stringizer/generic printer/test helpers.

@kazk
Copy link
Member

kazk commented Jan 19, 2024

To be honest I do not really see a good way to fit the C++ compilation model into the 3 snippets we have now. I think that repurposing preloaded will not prove to work well

Yeah, that's what I expected.

@ggorlen How is CCC C++ working for Qualified?

that ideal solution would be to introduce two more tabs (for solution.h visible to authors and users, and preloaded.h editable only by authors)

This won't happen. I can see Codewars eventually adding support for projects challenges (allows you to add files) like Qualified in the future.

employ some runner-side preprocessing and use markers in submitted code snippets

Yeah, I guess we can support this for when the default doesn't work well. The runner can see if any markers are included and handle the submission differently.

The markers and preprocessing could be potentially backed by the #line X some_filename directive.

Can you elaborate this directive?

@hobovsky
Copy link

hobovsky commented Jan 19, 2024

See https://gist.github.com/kazk/3732ef1b693a3c4483a0b8e75f0b524a for a list with a basic summary for each.

Looking briefly through the list, there is nothing in preloaded what couldnt be worked around:

  • include-only preloadeds should be removed anyway
  • stringizer-only preloadeds are not related to any new setup
  • almost all (all?) preloadeds which contain some definitions common for a) sample tests and full tests, or b) user solution and tests, can be worked around by keeping definitions in the preloaded, and redeclaring all the stuff explicitly in solution and tests. It's not a great technique due to code duplication and possibility of both versions diverging at some point causing problems, but at least it is not a showstopper. This applies to preloadeds which define types (typedefs, classes, interfaces), as well as data (global variables, dictionaries, etc.).

As a bottom line, if there were no preloaded.h, and only preloaded.cpp, I think majority of kata could be made to work (not the other way round tho).

The interesting part which you did not show is solutions (and maybe solution setups) which contain template keyword or #define directive, as these are effective only in a translation unit they reside. As an effect, if they would be located in an implementation file (i.e. solution.cpp), these things will not be possible to be tested. Solutions which are meant to be templates or macros have to be placed in a header file, and have to be included by tests (with some cave-ats, but generally they do).

Another idea: declare tasks which require users to provide solutions in a form of a template or a macro as unsupported. It would be a pity because it would prevent template metaprogramming tasks (or make them difficult to author), but most probably would also remove the necessity of having solution headers (if we verify, and agree, that re-declarations in tests work and are OK).


Can you elaborate this directive?

It's just a shot and it depends on what configuration of snippets will be finally used. Generally, the #line directive modifies behavior of __LINE__ and __FILE__ macros, which are eventually used by test macros like assertions when reporting failures. But since the test macros are usually present in test snippets (duh), it most probably will not be as useful as I thought it might be.

@kazk
Copy link
Member

kazk commented Jan 20, 2024

The interesting part which you did not show is solutions

48 kata with template/#define in the reference solution: https://gist.github.com/kazk/094df9ae7d5994f96e0bffa57ef3390a

@hobovsky
Copy link

Cool, I will try to do something useful with the lists over the weekend.

@error256
Copy link

As an effect, if they would be located in an implementation file (i.e. solution.cpp), these things will not be possible to be tested.

I think it's only a problem if there are both headery and linkable entities? Otherwise it should be possible to #include <solution.cpp> in the tests.

@hobovsky
Copy link

hobovsky commented Jan 20, 2024

IT might be just me, but something rubs me really bad when I see implementation files included as header files. Technically these are just files like every other so yeah, why not, but OTOH I am not sure I would call a setup which relies on including *.cpp files a step in a direction of a better, clearer setup. Maybe if the runner saved the snippets as both, a cpp file and a h file, then it would allow for clearer includes.

I will try to pick some kata from the lists and see if they can be set up in a way which would benefit from the #include "solution" or #include "preloaded".


EDIT: I took the kata Compile time #1 Factorial, which can be tricky in a new setup because its solution is a template. By applying Unnamed's suggestion I managed to run it locally after adding #include "solution.cpp" to tests snippet. So it works (for this kind of kata), but but the location of the solution.cpp has to be easily reachable from the tests snippet (the same directory, or a documented relative path, or added to location of includes in command line), and I still do not like the fact that the included file has an extension .cpp.

I will check if there are kata which mix linkable and non-linkable stuff in a solution, what would make this approach not valid for them.

EDIT: I took a look at kata which mix linkable and non-linkable elements in a solution. There is a bunch of them, and they fail to run in their current form, but since the mixed stuff is in majority cases helper functions, they can be fixed and made compliant to the #include "solution" idea. Examples can be the "Moves in squared strings" series, where solution is a class, and author's solution uses a class definition with method declarations, and method definitions outside of the class. The solution does not compile this way in a new setup, but moving the definitions inside of the class fixes the problem. But even then, the restriction of not having method definitions outside of a class looks to me as imposed somewhat artificially and I am not sure I would like to force authors to follow some specific patterns, and disallow some other patterns which are generally valid in the language.

The only kata which seems to be impossible to fit into a setup without distinct snippets for solution.h and solution.cpp (or preloaded.h and preloaded.cpp) seem to be the Unique In Order and I think the Adapter Pattern - Geese to Ducks.

@greg-gorlen-andela
Copy link

@kazk I skimmed the thread but I'm not sure I'm totally ramped up and understand the issues at hand, so bear with me.

@ggorlen How is CCC C++ working for Qualified?

Do you mean "how does it work?" or "how is it working out for us?"--I assume the latter. I haven't had any blockers, just some fussiness figuring out name clashes between the solution and preloaded files, or something along those lines that I can't remember too well. I haven't worked on the C++ content in a good while.

Let me know if there are any particular concerns and I'll see what I can offer.

@hobovsky
Copy link

I created a prototype of a setup using a preprocessor: codewars/next-cpp#4 . Please note that it's by no means normative and I just hacked something to make it work in my local docker, and many things are most probably not suitable for a final CW setup. I will try to add more examples of snippets from migrating existing, potentially problematic kata, showcasing various approaches.

@kazk
Copy link
Member

kazk commented Jan 23, 2024

Thanks Greg. Yeah, I mostly wanted to know if you saw any limitations or had any suggestions to how the classic code challenge works for C++.

Thanks @hobovsky. I'll take a look.

@Feliks-WR
Copy link

Use GCC.
It even support C++23 already!

@hobovsky
Copy link

hobovsky commented Jun 7, 2024

Possibly superseded by #307

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Next Up
Development

No branches or pull requests