SFML community forums

General => SFML development => Topic started by: eXpl0it3r on February 22, 2017, 05:09:38 pm

Title: C++ standards
Post by: eXpl0it3r on February 22, 2017, 05:09:38 pm
Info & Rules (http://en.sfml-dev.org/forums/index.php?topic=21541.0) about this sub-forum

SFML 2.x is currently stuck with C++03 and it's starting to show in various places. For SFML 3 we had decided already quite a while ago, that we will be using C++11. In the meantime however, C++14 has become widely spread and most compilers out there support all or all important features of the C++14 standard. While SFML 3 is in development for the next x months, one might even ask yourself, whether C++17 might an option.

In this discussion, we want to focus on what features of the new C++ standards SFML can make use of and how these language features should be applied. However, this discussion is not about whether standard classes such as std::thread/std::chrono should replace the SFML's equivalents; those will be discussed separately.

Here are some points that might aid as foundation for the discussion.

Let's start things off with a recently written list of questions by binary1248.

Quote from: binary1248
  • When/Where do we use initializer lists? Everywhere possible, or only in certain scenarios?
  • Uniform initialization? {} everywhere or () as it was in C++03?
  • Almost always auto? Or are there cases when auto is not desired?
  • When do we start using decltype instead of having to type out something that can't be auto deduced?
  • Do we use generic lambdas (C++14)? Or C++11 non-generic lambdas?
  • How do we format lambdas?
  • Do we rather specify the lambda return type or static_cast a return value that causes ambiguity?
  • I assume we make use of override everywhere where it makes sense?
  • When do we use nullptr? Everywhere? Even when talking with OS APIs that use the NULL define?
  • When do we make use of strongly typed enumerations? Everywhere? Or are there exceptions?
  • Rule of Zero everywhere possible and Rule of Five elsewhere? :P (I am actually a firm believer of this.)

Related topics
Summary

C++14 features
Tasks
Title: Re: C++ standards
Post by: DarkRoku12 on February 22, 2017, 05:31:24 pm
Quote
C++11, C++14, C++17?
I think C++11 would be the best option.
C++17 its too new, i think the new standard is more focused on Multithreading and Parallelization.
The most useful new library on C++17 (for SFML) would be FileSystem.

Quote
Code simplification: smart pointers, type inference, range-based for, delegating/inheriting constructors, nullptr, lambda expressions, std::function, std::tuple
All of those are good, but IMHO its better to let the user use smart pointers for its own and don't impose them.


Quote
[[deprecated]] attribute (C++14)
I think it is necessary.
Title: Re: C++ standards
Post by: Laurent on February 22, 2017, 06:16:19 pm
Quote
C++11, C++14, C++17?
I don't think this is the right question to ask. Let's instead think about the language features that we would need in SFML 3, and then check their availability in our target compilers. Whether it belongs to C++11, 14 or 17 is less important, as some compilers may not implement all features of an old C++ version while well supporting some features of the upcoming standard.

My personal opinion: we mainly need the most important features of C++11 (brace initializers, move semantics, new standard classes) and shouldn't bother too much about newer stuff. The only exception would be C++14's [[deprecated]], so we should check whether it is well supported or not.

Then the most important point will be to have old compilers (to be defined clearly) in our CI system, and make sure that it SFML compiles on those, then we are safe for the rest of the world.

Quote
Move semantics for resource classes
Of course! Any new idiom of the language should be applied (and especially this one!), as long as it doesn't involve bleeding-edge language features.

Quote
Remove component-wise overloads in favor of initializer lists: setPosition(x,y) -> setPosition({x,y})
Keeping them wouldn't make sense.

Quote
Code simplification: smart pointers, type inference, range-based for, delegating/inheriting constructors, nullptr, lambda expressions, std::function, std::tuple
As I said, let's use everything that is available. Why would we keep old syntax when there's better one available?

Quote
[[deprecated]] attribute (C++14)
To me, this one is the only real question of this topic ;D
Title: Re: C++ standards
Post by: binary1248 on February 22, 2017, 06:40:40 pm
The only real reason I would be a bit annoyed at only being able to use C++11 is that the standards committee somehow managed to forget std::make_unique<T>(...) and only got around to adding it in C++14. I've written my own version of it several times, but it like I said... one of those annoying little things. ;D
Title: Re: C++ standards
Post by: Elias Daler on February 23, 2017, 12:15:54 am
Agreed, C++14 should be used: it's supported almost everywhere where C++11 is supported and fixes some problems and overlooked stuff of C++11. (make_unique is a big one!). And I also like generic lambdas a lot, they make lambda code much cleaner sometimes.

P. S. Should I start using setX({x, y}) instead of setX(x, y) if there are overloads for sf::Vector2<T> and T,T? Any noticeable differences or advantages?

P. P. S. Glad this discussion is up! I really want to see SFML moving forward and will be happy to help where I can.
Title: Re: C++ standards
Post by: binary1248 on February 23, 2017, 01:15:23 am
P. S. Should I start using setX({x, y}) instead of setX(x, y) if there are overloads for sf::Vector2<T> and T,T? Any noticeable differences or advantages?
If your compiler/optimizer isn't complete garbage, the 2 variants should produce the exact same code if it has access to the call site as well as the called implementation. Since sf::Vector is a template and we are making heavy use of value semantics here, the optimizer should also have an easy job of understanding what we intend to do and just "produce the right output". I stress the second part of the first sentence because it is one of the most important factors when considering what can and can't be optimized.

When producing a library, information about the source code and the original intention of the developer is lost once the intermediate form is produced. Without this information, the optimizer simply put "can't be smart about things". Both function implementations will have to be available via the external interface of a library, even if it is obvious that calling either would lead to the exact same effects. In this case temporary object construction, or whatever the technical term for it is, also can't be avoided because it would manipulate the structure of the call itself. This is why the only "magic" that happens when enabling link-time optimization (or LTCG in Visual Studio) is that a copy or some form of the original code (such as an AST) is included with the intermediate form. With it, the optimizer still has a chance to be smart even after transforming the original code into an intermediate form, treating the intermediate form a bit like a header-only library in some sense when performing the final link.

As weird as it sounds, although both setX({x, y}) and setX(x, y) do the exact same, the second has better chances of resulting in faster code when this function is at the boundary of a library.

And just food for a (thought) experiment: If we had a mechanical way to transform SFML into a header-only library, sure it will take a fair bit longer to build your application, but I can guarantee you that it will also run faster than it does "linking the traditional way". Nothing other than your usual trade-off. I've seen this many times in the past, and I myself also make use of this phenomenon when I have to write highly optimizable cross-platform code for work.
Title: Re: C++ standards
Post by: Elias Daler on February 23, 2017, 09:51:11 am
binary1248, thank you for the detailed explanation! :D
The concept of being header-only is interesting... wonder what things compiler may be able to optimize with that.

Thinking about C++14 a bit more... the thing that was missing in VS for a long time is improved constexpr. I don't think that SFML needs much of it, so a lot of versions of VS will still be supported if C++14 is chosen.
Or maybe SFML can benefit from constexpr in some way?
Title: Re: C++ standards
Post by: Jonny on February 24, 2017, 01:55:56 pm
I pretty much agree with Laurent about language features dictating which c++version to use, but in general I'd limit it to c++11 and below, as compiler support can still be a little patchy for some c++14 features (some c++14 features would even rule out all VS versions...)

  • Remove component-wise overloads in favor of initializer lists: setPosition(x,y) -> setPosition({x,y})
I'm completely in support of this.

  • [[deprecated]] attribute (C++14)
I don't beleive this is even supported in vs2015 unfortunately (yet)...

Based on this page: https://msdn.microsoft.com/en-us/library/hh567368.aspx

For me in vs2015 it also compiles but doesn't report anything, which I guess is better than failing to compile
Title: Re: C++ standards
Post by: Satus on February 24, 2017, 02:22:38 pm
Quote
I don't beleive this is even supported in vs2015 unfortunately (yet)...

It will compile, just won't report anything.

Hm, I'm not sure that the VS2015 I use at work (the one I checked this with) is updated to the latest version. Though it says Update 3.
Maybe it's something with my project setting.
Title: Re: C++ standards
Post by: JayhawkZombie on February 24, 2017, 03:20:01 pm
It will compile, just won't report anything.

Odd.  VS 2015 reports to me when I use this tag.

eg
  [[deprecated]]
  static int TextEditCallbackStub(ImGuiTextEditCallbackData* data)...
I get the following warning:
1>sfml_project\main.cpp(121): warning C4996: 'EConsole::TextEditCallbackStub': was declared deprecated

Hmm. I'm using version 14.0.25425.01, Update 3, if that's of any importance.  I'm not sure why it'd report for some but not others.
Title: Re: C++ standards
Post by: Hiura on February 24, 2017, 06:56:56 pm
A few comments on the language features.

Quote
Almost always auto? Or are there cases when auto is not desired?
Do we use generic lambdas (C++14)? Or C++11 non-generic lambdas?

I think using auto almost everywhere is good. There are however places where we should refrain from using this feature, mainly for readability and sanity purposes. It's really great to replace lengthy types (e.g. iterators) or when we don't actually care about the type itself. But we should probably manually write the type we want to use if several types could be possible depending only on some subtle factors (I'm thinking about all the arithmetic types here) or if we want to avoid unintended type conversions.

C++14 generic lambda are here for a reason too: when the type of the arguments are obvious, `auto` is perfectly adapted.

In other words, I believe type inference should be used whenever possible but we should clearly tag variable with an explicit type when some confusing type deduction rules happen. I encourage people to read this SO answer: http://stackoverflow.com/a/15726504/520217


Quote
Do we rather specify the lambda return type or static_cast a return value that causes ambiguity?
Lambda should be used for simple functions, so if the return type is too complex or non-obvious in the context of the lambda, it should probably be a a function instead. With that in mind, the return type should be omitted most of the time and preferred over static_cast in my opinion.


Quote
Uniform initialization? {} everywhere or () as it was in C++03?
Using `{}` to init var is better than using `()` to trigger errors instead of weak warning when some unintended conversion occurs. However, when calling the ctor of an object with multiple arguments, we should probably use `()` when there is one overload (that we don't want to use) of the constructor taking an `std::initializer_list` to avoid potential confusion.


Quote
I assume we make use of override everywhere where it makes sense?
and `final`. :-)

Quote
When do we make use of strongly typed enumerations? Everywhere? Or are there exceptions?
I guess there could be some exceptions, but usually I'd go for strongly types enum.

Quote
Rule of Zero everywhere possible and Rule of Five elsewhere? :P (I am actually a firm believer of this.)
The rule of five has the advantage to make things clear and documented, so I'd vote for this one.

As for C++17, there are some nice features:
 - `std::optional` is a nice library addition -- not sure how we can leverage this however,
 - nested namespace declaration would be nice to have, but in itself cannot justify to use this standard,
 - attribute for enumerators would be interesting in the future to mark some as deprecated but for v3.0 this should not be required,
 - improvements on if (constexpr + if(init; cond)) could be nice to have for readability purposes,
 - structure binding would be nice for Vector2/3 (API-wise) -- considering this as a conditionally supported would be good IMO.
Title: Re: C++ standards
Post by: Elias Daler on February 26, 2017, 09:33:36 am
Quote
The rule of five has the advantage to make things clear and documented, so I'd vote for this one.
What do you mean by that? I think that we should use Rule of Zero as much as possible and only use Rule of Five if we really have to (e.g. if object needs a non-trivial copy-ctor => need to declare everything else). Or maybe I misunderstood you and that's what you meant?
Title: Re: C++ standards
Post by: Hiura on February 26, 2017, 05:59:12 pm
What do you mean by that? I think that we should use Rule of Zero as much as possible and only use Rule of Five if we really have to (e.g. if object needs a non-trivial copy-ctor => need to declare everything else). Or maybe I misunderstood you and that's what you meant?
I guess I don't really like implicit things in my code, so that's why I'm in favour of explicitly defining (with `= default` or `= delete`) all of them. Some argue that's too verbose, but I think it's a good practice against the complexity of the rules involved for automatic special members generation (the fact that Scott Meyers dedicated an item in EMC++ is a good clue how complex this is).
Title: Re: C++ standards
Post by: Elias Daler on February 27, 2017, 12:23:26 am
Oh, I see. I think that it makes sense in cases where one of the following gets written: dtor, copy-ctor, copy-op=, move-ctor, move-op=. In this case some of the rules of special members generation takes place and it may be hard to remember.

But in case of simple structs and classes, which have none of these, there's no need to do this because everything gets generated always.
Title: Re: C++ standards
Post by: Laurent on February 27, 2017, 11:09:59 am
By the way, won't we get some problems with the Android toolchain? Today I was trying to compile C++ code on Android, and the compiler threw an error at me because it didn't know std::to_string.
Title: Re: C++ standards
Post by: Mario on February 27, 2017, 11:45:32 am
Shouldn't be a problem, I think it just needs some adjustment (or potentially a switch to Clang). Haven't tried it though, but it should be supported.
Title: Re: C++ standards
Post by: Hiura on March 01, 2017, 05:08:03 pm
But in case of simple structs and classes, which have none of these, there's no need to do this because everything gets generated always.

PODs are indeed a different thing and therefore need different rules.

Anyway, this is more or less a detail -- as long as the rational is properly documented in the Code Style Guide it's not a significant problem for us in practice I think.
Title: Re: C++ standards
Post by: DeathRay2K on March 02, 2017, 09:17:50 pm
And just food for a (thought) experiment: If we had a mechanical way to transform SFML into a header-only library, sure it will take a fair bit longer to build your application, but I can guarantee you that it will also run faster than it does "linking the traditional way".
I know this is a bit tangential to the topic, but this would be fantastic.

On Rule of Five vs Zero, I think Zero when possible makes it more clear. That way, if in future you do need to change from one to the other, you won't forget to implement or remove any methods,.
Title: Re: C++ standards
Post by: Nexus on March 10, 2017, 11:21:53 pm
I'd definitely vote for the Rule of Zero. I'm a big advocate of reducing unneeded boilerplate code, I even went as far as writing a smart pointer for deep copies (http://www.bromeon.ch/libraries/aurora/tutorials/v1.0/smartptr.html), to avoid the hassle of writing the Big Three/Five.

I would not use auto where it doesn't clearly help the readability of code (mostly iterator declarations and lambda expressions). Removing types from code can decrease expressivity and require additional lookups to understand a code's context. I also wouldn't use the trailing or inferred return type unless dealing with heavy template code.
Title: Re: C++ standards
Post by: Turbine on May 10, 2017, 07:49:55 pm
Could you consider also using r-value moving, using "Type&& val" and "std::move()".

It'd sure save a lot of useless copying for position/proportion/string constructors and setters.
Title: Re: C++ standards
Post by: Nexus on May 22, 2017, 09:20:09 am
Move semantics will definitely be used, as already the lowest C++ standard being discussed (C++11) supports them.

For positions (or other value types that store all the data in the object itself) they don't make sense however.
Title: Re: C++ standards
Post by: eigenbom on November 13, 2017, 02:55:35 am
I highly agree with updating the c++ version. Some thoughts:
Don't want to bikeshed, but I'll just to say that less use of auto is better. e.g. the auto here makes the code a little harder to follow:

auto bounds = sprite.getLocalBounds();
rectf bounds = sprite.getLocalBounds();

Title: Re: C++ standards
Post by: MorleyDev on November 14, 2017, 04:39:20 pm
I'd actually argue that the problem there isn't auto, it's that using auto reveals "getLocalBounds" isn't sufficiently named and instead should be something like:
auto bounds = sprite.getLocalBoundingRect();

But I'm a "type deduce all of the things" type of developer. I use var almost exclusively in C#, and tend to favour the approach closer to functional languages where you let the compiler figure out at much as possible. Types are just the contracts of the code, and only exist to catch contract violations at compile time and to work with the names of things to provide self-fulfilling documentation for those contracts.

However, C++ being a recent addition to the world of type deduction, I'd understand if the SFML team were skittish about committing whole to it to such a degree.
Title: Re: C++ standards
Post by: Laurent on November 14, 2017, 06:02:07 pm
The use of "auto" to deduce a variable type happens either in your own code or in SFML internal code. So how what we'll decide would change the users life in any way?
Title: Re: C++ standards
Post by: MorleyDev on November 14, 2017, 08:23:51 pm
I was merely weighing in with a counter-point to the "being explicit improves readability" argument, namely that the fault could be said to lie in the functions name, and auto helps avoid being overly explicit and capturing what is actually meant, the type information being largely tangential or even a distraction to the user outside of documenting and capturing contract violations.

My last comment, that I understand why the SFML team would avoid doing so, was also not meant as in "not doing so would negatively impact me", but as in auto is relatively new to C++, and keeping closer to a style other long-standing C++ developers would be more familiar with, thereby not putting off developers from submitting pull requests for outstanding issues due to the code being 'too different from what they are used to', may be considered a reason to avoid heavy use of auto in and of itself.

Sorry that wasn't clear.
Title: Re: C++ standards
Post by: Laurent on November 14, 2017, 08:41:45 pm
My reply wasn't targetted specifically at you, it was just a general comment to the discussion about "auto" ;)
Title: Re: C++ standards
Post by: MorleyDev on November 14, 2017, 08:48:36 pm
My reply wasn't targetted specifically at you, it was just a general comment to the discussion about "auto" ;)

My apologies, jumped the gun a bit there I'm afraid. Whilst auto as a whole doesn't affect the end user, it is one of those things developers love to get worked up about isn't it? Though the adoption of such things does raise a question as to whether adopting them risks putting off the 'old guard' of C++ developers (though I imagine auto would actually feel very familiar to developers used to most of the not-Java-or-pre-C++11-languages).

Actually, that is a thought I think I may have stumbled on in my needless clarification. A lot of the examples I see coming out of the C++ committee members of late seem to use auto fairly regularly, though that may be a selection bias on my part. This makes me wonder if the C++ committee are attempting or hoping to take C++ into an 'auto-first' mindset.

And if that is the case, that poses the question of whether SFML should follow suit. And likewise if that is not the case, I am experiencing selection bias and as a whole the C++ committee members are fairly auto-light or auto-middling, that poses the same question as to whether SFML should again follow suit and adopt their approach.

That then goes into should SFML seek to follow the lead of the C++ committee members in general or not in terms of code style (snake_case aside because....just...just because).
Title: Re: C++ standards
Post by: jamesL on January 08, 2018, 08:57:42 pm
read this today which I thought had some nice examples

From C++ 11 to C++ 17: A Walkthrough

https://www.codeproject.com/Articles/1221623/From-Cplusplus-to-Cplusplus-A-Walkthrough
Title: Re: C++ standards
Post by: Ceylo on January 10, 2018, 11:00:31 pm
This is funny to see here more or less the same discussion that we had at my workplace :D

What I'd recommend:
- take latest versions supported by the main compilers you work with, only considering their very latest version. You're talking about future so it's not the time to even consider non-latest compilers. And deduce standard C++ you case use from that
- don't ask yourself if you need latest usable standard, just use it, you don't want to spend again time to decide whether standard should be upgraded if you could have done it 3 years earlier for the same price
- don't bother defining too many rules, you'll see over time how it feels, just try to keep code simple and be smart. So for example you don't need to define when auto should or shouldn't be used because: either way it doesn't make such a big difference in most cases so wearing your keyboard out isn't worth it :) , and whether it's appropriate really depends on contexts that you can't possibly all predict now
Title: Re: C++ standards
Post by: eXpl0it3r on January 10, 2018, 11:28:45 pm
- take latest versions supported by the main compilers you work with, only considering their very latest version. You're talking about future so it's not the time to even consider non-latest compilers. And deduce standard C++ you case use from that
- don't ask yourself if you need latest usable standard, just use it, you don't want to spend again time to decide whether standard should be upgraded if you could have done it 3 years earlier for the same price
I'm not sure if this is directed generally at everyone participating in the discussion or directed at SFML's development. SFML isn't just a tool we use. There's no company or one entity behind SFML that would define what is required or not, instead we're dependent on the community and there are some who would be left behind if we just ignored C++ standards.

Sure, the argument can also be made the other way around, that not moving forward with the standard just means we're push other people away. But if that's the case, then that's their decision. Everyone can use SFML, whether you use a new standard or not, it's up to you to decide if it's a game breaker that the library doesn't use modern C++ internally. Where as if we just picked C++17, because I'm using it right now, many won't even be able to compile SFML anymore and it would not be their decision.

If you're just a consumer of libraries and C++ in order to build end user applications, then sure, just go with it, as long as your team/business allows it, but once you write code for others, you can't just ignore their requirements.
Title: Re: C++ standards
Post by: Ceylo on January 10, 2018, 11:35:28 pm
Sorry I was not very clear in my previous post but you're right. When saying "take latest versions supported by the main compilers you work with" I actually meant "take latest versions supported by the main compilers you and your users work with".

I guess this addresses your comment :)

Edit: implicitly this also means that if you user use a compiler version that don't support the standard you'd like to use, but the latest version of that compiler does, just ask them to update their compiler.
Title: Re: C++ standards
Post by: eXpl0it3r on January 10, 2018, 11:50:03 pm
Edit: implicitly this also means that if you user use a compiler version that don't support the standard you'd like to use, but the latest version of that compiler does, just ask them to update their compiler.
If it were always that easy, nobody would be using legacy-anything. "Just update" is not always a viable solution unfortunately, which is why we want to make a clean cut at one point (version 2.x is C++03, version 3.x is C++1Y).
Title: Re: C++ standards
Post by: Klaim on August 28, 2018, 02:38:36 pm
Here is my current opinion, considering SFML:
Go with C+17.

Aguments:

 - std::filesystem : if SFML relies on it by default (or not use filesystem at all and let the user feed SFML), the codebase would be reduced;
 - std::string_view: There are several (not all) interfaces of SFML that take std::string while std::string_view would be a far better default. Notably the API for passing shader scripts (which imply a lot of copies). I pointed this issue before but the (reasonable) answer was that adding a string-ref type would be another thing to maintain, and there is no SFML dependency providing one. With C++17 std::string_view would do the job.
 - std::any and std::optional might be very helpful in several SFML APIs evolutions.
 - it's completely implemented by major compilers (I think there might be holes that SFML will not use anyway);
 - if the next release of SFML happen around the end of the year or next year, there will be about a year before the following standard is ratified (and a lot of it's stabilized features are already implemented in at least 2 compilers);
 - backward compatibility should be good enough to not force users to change their code (except for changing APIs);
 - it's the simplest way to open the possibility of reducing drastically codebase size (less code, less bugs - most of the time) (I'm htinkin both C++14 and C++17 here);
 - changing the C++ version do not mean that all the code have to be upgraded immediately or ever, but it makes it possible and easy to check;


I was wondering: what are the arguments against going directly to the current standard? It's not really clear from the current discussions.
Title: Re: C++ standards
Post by: Nexus on September 01, 2018, 02:37:42 pm
Klaim brings up some really good points.

C++14 was a small addition, at least compared to C++11 -- I saw it mainly as attempt to make features introduced in C++11 more complete and consistent. There were not many library additions, mostly smoothing the corners of language features.

C++17 is different, with std::optional, std::filesystem and std::string_view as probably most impactful library features. While the latter is mainly an optimization, optionals allow APIs to be more expressive, and avoid workarounds like the return-bool-and-output-parameter idiom.

By the way, I found a nice overview over different standards' features (https://github.com/AnthonyCalandra/modern-cpp-features).

When choosing a standard, we need to decide:
The last point is important. If we were to choose C++14 at this very moment, it's already "outdated" by 4 years. Add to that the time until SFML 3 is ready. "Outdated" in quotes because C++14 does not expire, it has however been superseded by more recent versions.
Title: Re: C++ standards
Post by: Rosme on September 05, 2018, 02:19:23 pm
About the recent compiler thing, according to this page (https://en.cppreference.com/w/cpp/compiler_support) which is quite up to date, C++17 is pretty much supported by every major compiler that most people uses (MSVC, GCC, Clang). So going the C++17 way for a version that will probably be out in two or three years at least seems like a normal choice. Even if SFML 3 would come out today it would makes sense.

There was a time where it was somewhat recurent(at least in IRC) for people to ask why doesn't SFML support filesystems. That kind of question can easily be solved with C++17 by using std::filesystem. There was a time where SFML was considered more modern than SDL for using hardware acceleration. If we don't go with a recent well supported standard, well SFML is not exactly modern anymore. Just my 2cents for supporting C++17.
Title: Re: C++ standards
Post by: Elias Daler on September 05, 2018, 02:57:55 pm
I'm not sure C++17 will bring much positives to SFML. Are there many C++17 libraries out there which are not super-complex and/or template-heavy?

Unless there are strong examples of using std::optional, std::any and other stuff to make SFML's API better, I don't see why C++17 will be really useful.
Title: Re: C++ standards
Post by: dabbertorres on September 05, 2018, 09:46:51 pm
I imagine constexpr-if could be useful for platform specific code.

I know I'd find std::string_view and std::filesystem useful as well.
Title: Re: C++ standards
Post by: Laurent on September 05, 2018, 09:59:11 pm
Everyone talks about std::filesystem but it would be an internal detail, end users wouldn't see any difference. And anyone can already use std::filesystem or anything from C++17 in its own code with a C++03 SFML right now, of course.

std::string_view, how would it deal with sf::String?

And I don't think it's about C++17 or not, it's more about the features that we need. Compilers usually implement stuff gradually anyway, they don't suddenly get all the new C++17 stuff right after the standard is officially out. Some features are well supported very soon, even before they get validated, some others take more time.
Title: Re: C++ standards
Post by: Elias Daler on September 05, 2018, 10:36:47 pm
Yeah, as far as I know there's no std::filesystem on the latest XCode on Mac OS X... imagine that.

I imagine constexpr-if could be useful for platform specific code.
Not really. SFML has it neatly separated into different impl cpp files. And #ifdefs are still ok for platform specific stuff.

std::string_view has so many gotchas, that I've been staying away from it, but maybe I just had a bad experience. :)

Even if all current compilers support C++17 well (and MSVC, Clang and GCC do), you still need to remember about iOS and Android which usually lag in terms of compilers... And some distros don't have latest GCC/Clang in them, so you get 100% C++14, but 50% C++17. I think this will still be the case for the next 3-5 years.
Title: Re: C++ standards
Post by: dabbertorres on September 07, 2018, 12:40:10 am
Everyone talks about std::filesystem but it would be an internal detail, end users wouldn't see any difference. And anyone can already use std::filesystem or anything from C++17 in its own code with a C++03 SFML right now, of course.
True.

std::string_view, how would it deal with sf::String?
Not directly with sf::String. One, although not very important (minor optimization, maybe), place it could be useful would be with sf::Shader::setUniform, which is using const std::string&.

And I don't think it's about C++17 or not, it's more about the features that we need.
Agreed! Plus, if desired, I know CMake has ways of specifying required language/library features which could be useful for identifying supported compilers and whatnot, based on a defined feature-set.

I imagine constexpr-if could be useful for platform specific code.
Not really. SFML has it neatly separated into different impl cpp files. And #ifdefs are still ok for platform specific stuff.
True!

Yeah, as far as I know there's no std::filesystem on the latest XCode on Mac OS X... imagine that.
Oof. I keep hearing things that make me glad I don't have to work that, haha.
Title: Re: C++ standards
Post by: barnack on September 07, 2018, 03:10:04 am
it's more about the features that we need.
That's a good point about something i noticed eXpl0it3r wrote: "Code simplification: smart pointers".
Do we really need that?
I might not be an expert about programming, but if the existing codebase is working internally with good old pointers AND without memory leak issues (i'm supposing it does), which means dynamic memory is properly managed, then what's the point of replacing them with smart pointers?
In my point of view smart pointers can help to make quick code, can allow the programmer to be more lazy, but they take this small amount of resources more than normal pointers to, which in the case of an already robust code seems just a waste to me.
Am i missing something?

Sorry for the bad english, i've been awake since more than 48 hours  ::)
Title: Re: C++ standards
Post by: Laurent on September 07, 2018, 08:00:21 am
Quote
I might not be an expert about programming, but if the existing codebase is working internally with good old pointers AND without memory leak issues (i'm supposing it does), which means dynamic memory is properly managed, then what's the point of replacing them with smart pointers?
This is often a valid point. But in our case, we really need to modernize the code base. The main advantage is easier maintenance, and consistency with new code (which will be written using modern C++). Writing unit tests first (which is what we're doing) will help there, to ensure no regression while rewriting the code.

Quote
In my point of view smart pointers can help to make quick code, can allow the programmer to be more lazy,
No. The point of these utility classes is to write safer code.

Quote
but they take this small amount of resources
They don't. They can even be lighter than the code you would have to write without them.
Title: Re: C++ standards
Post by: Elias Daler on September 09, 2018, 11:26:08 am
Quote
In my point of view smart pointers can help to make quick code, can allow the programmer to be more lazy,
No. The point of these utility classes is to write safer code.
And not just safer, but also smaller. and easier to read. Destructors are rarely written, same with "cleanup" sections of functions, catching of exceptions to clean up the stuff that was previously allocated, and so on.

Title: Re: C++ standards
Post by: dabbertorres on September 09, 2018, 10:39:17 pm
Writing unit tests first (which is what we're doing)
Is this on GitHub? I don't see a branch or anything that looks like it at a glance (In the interest of helping, if possible).
Title: Re: C++ standards
Post by: eXpl0it3r on September 09, 2018, 10:56:24 pm
Is this on GitHub? I don't see a branch or anything that looks like it at a glance (In the interest of helping, if possible).
You don't have to look far. ;)

https://en.sfml-dev.org/forums/index.php?topic=16184.0
https://github.com/SFML/SFML/commits/feature/unittest
https://github.com/SFML/SFML/pull/1475
Title: Re: C++ standards
Post by: dabbertorres on September 10, 2018, 12:39:11 am
Oof, guess I'm blind. Thanks.
Title: Re: C++ standards
Post by: Gleade on October 15, 2018, 01:48:48 am
- take latest versions supported by the main compilers you work with, only considering their very latest version. You're talking about future so it's not the time to even consider non-latest compilers. And deduce standard C++ you case use from that
- don't ask yourself if you need latest usable standard, just use it, you don't want to spend again time to decide whether standard should be upgraded if you could have done it 3 years earlier for the same price
I'm not sure if this is directed generally at everyone participating in the discussion or directed at SFML's development. SFML isn't just a tool we use. There's no company or one entity behind SFML that would define what is required or not, instead we're dependent on the community and there are some who would be left behind if we just ignored C++ standards.

Sure, the argument can also be made the other way around, that not moving forward with the standard just means we're push other people away. But if that's the case, then that's their decision. Everyone can use SFML, whether you use a new standard or not, it's up to you to decide if it's a game breaker that the library doesn't use modern C++ internally. Where as if we just picked C++17, because I'm using it right now, many won't even be able to compile SFML anymore and it would not be their decision.

If you're just a consumer of libraries and C++ in order to build end user applications, then sure, just go with it, as long as your team/business allows it, but once you write code for others, you can't just ignore their requirements.

I'm quoting this entire post to give my post context.

Where as if we just picked C++17, because I'm using it right now, many won't even be able to compile SFML anymore and it would not be their decision.

Who is "many"? Have there been surveys to reflect who is using what standard/compiler? I'd be curious to know how many users of SFML are using legacy hardware/compilers.
Also; wouldn't using a compiler not up-to-date be a choice in the 99% of cases?

I think a decision shouldn't be based on assumptions.


But in our case, we really need to modernize the code base. The main advantage is easier maintenance, and consistency with new code (which will be written using modern C++). Writing unit tests first (which is what we're doing) will help there, to ensure no regression while rewriting the code.

This to me is the perfect answer.
Title: Re: C++ standards
Post by: markand on October 24, 2019, 03:08:08 pm
My $0.02, I think C++17 is the way to go. SFML 3 is not about to be released anytime soon and we're almost in 2020.

C++17 is even available in Visual Studio, Android and in major distributions. I think there is no good reasons to stick with C++11 or C++14.

Major features that C++17 offers:

Title: Re: C++ standards
Post by: Nexus on June 17, 2020, 10:36:02 pm
What I wrote almost 2 years ago:
When choosing a standard, we need to decide:
  • Who are we targeting? Does our main user base have access to recent compilers?
  • What newer C++ features can SFML directly benefit from?
  • When would SFML 3 emerge?
The last point is important. If we were to choose C++14 at this very moment, it's already "outdated" by 4 years. Add to that the time until SFML 3 is ready.

And SFML 3 is still nowhere. So I'm no longer sure if this should be the criterion.

Would we even require a major version to add more modern C++ features?
A new C++ version is a breaking change only w.r.t. old compilers, it's not breaking client code. Intuitively, it appears to me that a typical SFML user has access to an at most 3 years old compiler (to support C++17).

My suggestion:SFML 2.6/2.7 could then be seen as a "proof-of-concept" of more modern features, and maybe based on that, we learn how to improve APIs for SFML 3.

Title: Re: C++ standards
Post by: eXpl0it3r on June 17, 2020, 11:07:27 pm
Given the time frame C++17 is what we're aiming for already, but with SFML 3.
Refactoring code without breaking API/staying SFML 2 compatible is an unnecessary burden.

I suggest you take a look at the currently planned Roadmap: https://en.sfml-dev.org/forums/index.php?topic=24372.0
Title: Re: C++ standards
Post by: Nexus on June 18, 2020, 11:10:40 pm
Thanks for the link, I missed that latest update. SFML 3 planned directly after 2.6 changes things of course.

I've added some more concrete suggestions (so far mostly on the C++ side) directly in the other thread.
Title: Re: C++ standards
Post by: Nexus on March 03, 2021, 07:30:35 pm
I elaborated the existing points in the C++17 solution design (https://github.com/SFML/SFML/wiki/SD:-CPP-17-Support) and added a few new ones. After discussing with eXpl0it3r, the plan is that we have a basic design on each feature before jumping into implementation. This will communicate clearly how we want to change things, and avoid that e.g. move semantics is implemented by 5 people in 6 different ways.

What I wrote down is a suggestion from my point of view, with the main criteria for inclusion being a) ease of use and b) pragmatism (don't change what helps no one). Things are not set in stone.

There are also quite a few open points, feel free to leave feedback! :)
Regarding move semantics, please use the dedicated thread (https://en.sfml-dev.org/forums/index.php?topic=27116.0).
Title: Re: C++ standards
Post by: Elias Daler on March 04, 2021, 12:37:58 am
Nice to see some activity happening here! Also I agree with most of the points here and I'm particularly glad that we won't overuse modern constructs like trailed return types or noexcept.

Quote
Occurrences of unscoped enumerations (enum) should generally be replaced with scoped enumerations. We would use the enum struct variant, not enum class, as enums come much closer to a "bundle of data" than "object-oriented entity with methods".

Can't agree with that one. I think "enum struct" is very obscure and more people use "enum class". For example, if you pick almost any modern C++ book - "Effective Modern C++", "C++17 The Complete Guide", "The C++ Programming Language", etc - all of them use "enum class" for their examples and don't even mention "enum struct" at all.
More examples:
Google C++ standards (https://google.github.io/styleguide/cppguide.html)
C++ Core Guidelines (https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md)
cppreference (https://en.cppreference.com/w/cpp/language/enum) - "enum struct"s are mentioned, but "enum class" are used in examples.

Quote
override and final
final is mostly pointless in my opinion. override is very good - it should be added everywhere, because it's a clear indication where something is overriding base-class virtual function + it adds additional compile-time checks that function signatures match.


Quote
using everywhere, or just for templates
I think using should be used everywhere instead of typedef as using is much clearer in every possible way, but especially for function pointers and multi-word types. Some examples:

typedef unsigned char Uint8;
// can become
using Uint8 = unsigned char;

typedef void(*ContextDestroyCallback)(void*);
// can become
using ContextDestroyCallback = void(*)(void*);
 



Also it would be nice to have something about attributes like [[nodiscard]], [[maybe_unused]] and [[deprecated]]. They can be helpful for improving API's clarity (and when we'll need to deprecate something in the future).
Title: Re: C++ standards
Post by: Nexus on March 04, 2021, 09:21:54 am
Thanks for the feedback!

enum struct vs. enum class: I don't have a very strong opinion here. Both are terrible cases of keyword recycling, and I guess the entire reasoning to even allow two variants is the old "I want to use struct whenever I can use class (except in template parameter lists)". I thought being public and data-only might be closer to struct, but let's see what others think here :)

final: what I definitely want to avoid is annotating classes final for no reason. It's one of the "wrong default" issues C++ has (like explicit, const, noexcept...), and the lack of it doesn't imply "this class is designed for inheritance". Regarding final for methods, it probably only makes sense when it's actively harmful to further override a method.

override: yes, I agree it should be used everywhere.

using: good point about the clarity.
I honestly think sf::UintN/IntN types should go too, there's no reason to maintain them with <cstdint> (https://en.cppreference.com/w/cpp/header/cstdint).

Attributes: absolutely agree, especially [[deprecated]] is great. Was thinking about them yesterday, but didn't know where to put it.
Title: Re: C++ standards
Post by: fallahn on March 04, 2021, 01:52:47 pm
final Can also help with devirtualization and offers performance increases in certain cases:

https://devblogs.microsoft.com/cppblog/the-performance-benefits-of-final-classes/