runner icon indicating copy to clipboard operation
runner copied to clipboard

Add C++ 20

Open barnasm opened this issue 4 years ago • 38 comments

Please complete the following information:

  • Name: C++
  • Version: 20
  • Release Note/Changelog: https://en.cppreference.com/w/cpp/compiler_support

:+1: reaction might help to get this request prioritized.

barnasm avatar Mar 24 '21 21:03 barnasm

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… https://github.com/codewars/runner/issues/42#issuecomment-719843559

Out of curiosity: Which features are you looking for?

Urfoex avatar Mar 25 '21 06:03 Urfoex

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?

barnasm avatar Mar 25 '21 11:03 barnasm

Ranges can at least be used somewhat with ranges-v3 library: https://github.com/codewars/runner/issues/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 https://github.com/codewars/runner/issues/87)

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

Also, currently Clang is used for compiling: https://github.com/codewars/runner/issues/42#issuecomment-719410228 With MSVC or GCC there would already be a bit more support.

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

Urfoex avatar Mar 25 '21 13:03 Urfoex

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

kazk avatar Mar 25 '21 23:03 kazk

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.

wrazik avatar Apr 27 '21 19:04 wrazik

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.

kazk avatar Apr 27 '21 19:04 kazk

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.

wrazik avatar Apr 27 '21 20:04 wrazik

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 :)

hobovsky avatar Apr 27 '21 20:04 hobovsky

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.

wrazik avatar Apr 27 '21 20:04 wrazik

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.

wtlgo avatar Apr 27 '21 20:04 wtlgo

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

mere-human avatar Jul 02 '22 18:07 mere-human

Any update ?

Hariom-Algo avatar Dec 29 '22 06:12 Hariom-Algo

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

FilipPlotnicki avatar Mar 09 '23 12:03 FilipPlotnicki

New Year 2024 is coming soon...

ozz-life avatar Sep 18 '23 22:09 ozz-life

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++.

bernb avatar Oct 06 '23 11:10 bernb

When will C++20 be added?

Waldisss avatar Jan 05 '24 12:01 Waldisss

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.

  • #52 lists why we should consider replacing Igloo
  • Global namespace pollution and conflicts:
    • #243
    • #142
    • https://github.com/codewars/runner/issues/87#issuecomment-719774878
  • Nested test groups are not supported, but it compiles and confuses users (#117)
  • Igloo is abandoned and we've been maintaining a fork. https://github.com/codewars/igloo

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 (https://github.com/codewars/runner/issues/193#issuecomment-1190815714).

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?

kazk avatar Jan 05 '24 20:01 kazk

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...

hobovsky avatar Jan 05 '24 21:01 hobovsky

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 avatar Jan 05 '24 22:01 kazk

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

kazk avatar Jan 19 '24 07:01 kazk

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 avatar Jan 19 '24 09:01 hobovsky

FYI https://github.com/codewars/next-cpp/issues/1

hobovsky avatar Jan 19 '24 16:01 hobovsky

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).

armeanco avatar Jan 19 '24 16:01 armeanco

  • 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 avatar Jan 19 '24 21:01 kazk

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?

kazk avatar Jan 19 '24 22:01 kazk

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.

hobovsky avatar Jan 19 '24 22:01 hobovsky

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

kazk avatar Jan 20 '24 02:01 kazk

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

hobovsky avatar Jan 20 '24 06:01 hobovsky

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.

error256 avatar Jan 20 '24 14:01 error256

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.

hobovsky avatar Jan 20 '24 19:01 hobovsky