Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Conditional C++11 Support  (Read 30027 times)

0 Members and 2 Guests are viewing this topic.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10800
    • View Profile
    • development blog
    • Email
Conditional C++11 Support
« on: July 05, 2014, 01:05:11 pm »
To not further spam this one issue - I already cleaned it up a bit - I thought, I open a thread here.

The subject at hand is, whether we should rewrite some things in SFML to place in conditional support for C++11, way before we most likely fully move to C++11 with SFML 3. And if we do so, what should be included as conditional support.

Points that should not be discussed here:
  • How much of C++11 which compiler supports. - We are aware that not all compilers support everything, but that's the reason why it would be conditional.
  • Detailed discussion on how something could be implemented. - This thread isn't here to discuss how the implementation should look like in detail.

Point that should be discussed here:
  • Should SFML implement conditional C++11 support?
  • Should SFML move to unconditional C++11 support at one point?
  • What feature should be considered for the conditional C++11 support?

Important point that have already been made:
Supporting C++11 will allow nice additions, but it won't replace many things. After this change, I think you'll still be able to write a program that uses mostly C++98, if you want to.

Regarding backward compatibility and maintenance of older versions, it's true that we'll move forward and focus on improving the latest versions, but I think it would be wise to spend some time back-porting bug fixes to the latest revision of the previous major version (i.e. 2.x after 3.0 is out). If we want SFML to be used in the real world, and not only for short-term small projects, we have to care a minimum about backward compatibility, and not abandon users who would not stick to the latest version. So where should the limit be? I don't know, but this should definitely be discussed.

Quote from: Laurent on GitHub
After a bit of research, it seems that I won't be able to make a single build of SFML that both supports C++03 and C++11. Mixing both can lead to binary incompatibilities.

In this case, C++11 cannot be added conditionnally, we'd have to wait until SFML completely switches to C++11 (not before SFML 3).

Quote from: GitHub
  • initializer lists
  • r-value references (move semantics)
  • some of the constructors can be made constexpr really easily (for example, sf::Color, sf::VectorN, sf::Rect).
  • sf::String could support the new Unicode character/string types.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Conditional C++11 Support
« Reply #1 on: July 05, 2014, 05:48:35 pm »
From a development point of view, I think people underestimate the amount of maintenance that would be required to have conditional C++11 support, i.e. separate builds for C++03 and C++11 which is the only feasible way to provide such support.

Either really ugly boilerplate macros would have to be inserted all over the place which would make reading and modifying the files a pain (go try to read through some boost headers that support multiple language variants) or the codebase would have to be split into a C++03 and C++11 implementation, which would mean a lot of code duplication and possibly having to modify multiple files to fix even trivial bugs.

Let's go through the reasons why we would still need C++03 support:
  • Currently used compiler doesn't support C++11
  • Platform does not support/provide a C++11 compatible compiler

The first point is a very commonly heard one. The assumption is that users might not be using a C++11 compatible compiler (yet?).

There are 3 mainstream compilers that we should aim to support 100%:
  • Visual Studio
  • GCC (includes MinGW)
  • clang

I think it is obvious which users would have issues compiling C++11 code.

GCC has had somewhat usable C++0x support since 4.6. 4.7 almost completed support for all language features and 4.8 completed support for all language features. I think it is safe to assume that any serious GCC user should currently have a C++11 capable compiler, even if not complete. I can't think of any compelling reasons why a GCC user would still be limited to a non-C++11 capable compiler outside of company politics.

clang... no debate here, it always supported a large subset of C++11 and is also currently complete.

Visual Studio... This is probably the primary reason why we are even considering keeping SFML C++03 compatible. I can understand that some managers don't fully understand the benefits of migrating to VS2013 or that platform limitations (i.e. Windows XP) prevent such an upgrade from taking place. But let's be honest, besides having to support old hardware that might only be able to run XP (which is EOL by the way), I can't see any other reason to stick with Windows XP as the platform to run applications on. Any truly new machine you would acquire these days would have an up-to-date Windows pre-installed on it if it even came with Windows pre-installed.

If you are using a current Windows and have hardware that can support VS2013 and yet still use an older development environment, either you've been working on a project for a long time and don't want to migrate mid-way, or you prefer supporting long-lived products using the original environment they were developed in (I can fully understand this). If you started a project after VS2013 was released and refused to migrate beforehand, then I really urge you to reconsider doing so. From personal experience, I've noticed myself become far more productive when using C++11 features effectively.

So to summarize, the only projects that I can understand need continued support for C++03 are those which:
  • Were started before C++11 was used seriously
  • Still need to be supported
  • Might be limited by platform restrictions
  • Were developed in Visual Studio

All of this means that SFML only really needs continued C++03 support for those users who have to provide support for their long-lived products that were made with SFML. This does not mean that those users would require the same support for newer products.

Taking into consideration that SFML only needs to maintain the stability of said products, this means that new features need not be added to old versions and platform specific bugfixes that do not target the user need not be added to old versions either. This would mean that SFML can progress with C++11 support as a requirement for all newer versions while backporting only necessary fixes to C++03 branches for the users that require them.

The effort required for backporting fixes to an older version of SFML would be much lower than simultaneously maintaining C++03 and C++11 builds. As already mentioned above, not even all bugfixes would have to be backported since only a small subset of users are actually truly limited to using C++03 and most of them as stated above as well, work on the same platform (Windows, Visual Studio). I would be happy to port them myself if requested to do so by someone who really needs them (meaning no "Can you port the fix back so I can continue using Ubuntu 8.04 please"). The effort of porting every now and then and working on a single C++11 build is much less than that required to maintain C++03 and C++11 at the same time.

I say we move on to full C++11 support in 3.x while dropping C++03 support for all future versions. Backports of fixes can be made when they are essential, but otherwise not. Everything becomes EOL at some point. Windows XP just went EOL in April, Ubuntu non-LTS goes EOL 1.5 years after release, Debian non-LTS goes EOL after 3 years, OS X... EOL after 2 releases? And SFML... EOL after 2 years... sounds reasonable to me.

P.S. My sincere apologies to any professional programmers and/or managers that I may have upset with this post. I was trying to be as objective as possible and posted everything in good conscience.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Conditional C++11 Support
« Reply #2 on: July 05, 2014, 06:17:31 pm »
It should also be noted that while some C++11 features provide additional optimizations or convenience for those who use it, others have a deeper influence on the design of the library. When providing only conditional C++11 support, then:
  • sf::Thread, sf::Mutex, sf::Lock and sf::ThreadLocal cannot be removed in favor of their standard counterparts
  • There will be further API restrictions, e.g. it's not possible to store non-copyable objects in STL containers or to return them from functions, and we need the namespace idiom to scope enumerations
  • A refactoring and simplification of several internal parts, especially regarding resource and thread management, will be prevented due to the lack of thread_local, std::unique_ptr, std::thread, std::mutex, std::atomic.
The price to pay for conditional support is, besides the points mentioned by binary1248, an unnecessarily big API and a more complex and potentially less robust/portable implementation.
« Last Edit: July 05, 2014, 06:23:07 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: Conditional C++11 Support
« Reply #3 on: July 06, 2014, 02:52:56 pm »
I'd be all for SFML 3 being C++11 only. Way I see it, SFML 2.x is perfectly usable when targeting-C++11 compilers and since C++11 aids in writing code that is simple and fast, SFML 3 would benefit from it.

Though I know this not the place to discuss missing features, there are still issues with C++11 implementations that could cause problems with compatibility. I'd argue SFML 3 would need some type of build server setup, even if it's just Travis-CI and AppVeyor to cover clang, g++ and visual studio, just because otherwise at some point the build is more likely to be accidentally broken for one of the compilers if we enable C++11 support.
« Last Edit: July 06, 2014, 03:07:15 pm by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Conditional C++11 Support
« Reply #4 on: July 06, 2014, 03:26:29 pm »
Quote
Should SFML implement conditional C++11 support?

No, implementing optional support means maintaining duplicated code and adding too much complexity to the code base.

Quote
Should SFML move to unconditional C++11 support at one point?

Yes, I totally agree with binary1248's view on this. There needs to be a cutoff point where all new development goes forward with full C++11 support while only back porting required fixes (no new features) to the old code base that is non C++11.

Quote
What feature should be considered for the conditional C++11 support?

Same as the first question, I don't think there should be any 'conditional support' in the SFML code base.

If we go ahead with C++11 support it should begin unconditionally with SFML 3 while keeping the 2.x code base compatible with non C++11 compilers.

I'd argue SFML 3 would need some type of build server setup

Tank is already working on a BuildBot build farm.
« Last Edit: July 06, 2014, 03:29:30 pm by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

binary1248

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1405
  • I am awesome.
    • View Profile
    • The server that really shouldn't be running
Re: Conditional C++11 Support
« Reply #5 on: July 06, 2014, 03:32:09 pm »
Though I know this not the place to discuss missing features, there are still issues with C++11 implementations that could cause problems with compatibility. I'd argue SFML 3 would need some type of build server setup, even if it's just Travis-CI and AppVeyor to cover clang, g++ and visual studio, just because otherwise at some point the build is more likely to be accidentally broken for one of the compilers if we enable C++11 support.
I think we don't have to go all out insane on the C++11 8). Working on SFGUI and SFNUL already gave me a bit of insight into what is and isn't supported by gcc, clang and VC. Most of the common features that have also gained public attention are supported by all of them, whereas features that not many know of and therefore not miss (such as lack of complete move support) are only unsupported by VS. GCC's standard library is also still incomplete in MinGW (and probably will be for a while), so that is also something to keep in mind.
SFGUI # SFNUL # GLS # Wyrm <- Why do I waste my time on such a useless project? Because I am awesome (first meaning).

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: Conditional C++11 Support
« Reply #6 on: July 06, 2014, 03:48:26 pm »
I'm just saying, it's still a more fractured a 'marketplace' than C++03 was.  If SFML allows C++11, then there is a need to declare which versions of the 'main' compilers/libraries to support. g++ 4.7? 4.8? 4.9? clang 3.3? clang 3.4? VC12? VC11? VC12 update? And there's a need to then not use features that break building on those compilers onwards.

For just not supporting C++11, this wasn't much of an issue since C++03 was well-established and fully implemented by the compilers. For C++11, it seems to me the complexity of ensuring support does increase. Now I'm still in favour of it, pros outweight cons, but I'd encourage appropriate steps taken to mitigate that complexity.
« Last Edit: July 06, 2014, 05:02:33 pm by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 10800
    • View Profile
    • development blog
    • Email
AW: Conditional C++11 Support
« Reply #7 on: July 06, 2014, 04:23:12 pm »
Please don't make this thread again about which compiler supports what.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

MorleyDev

  • Full Member
  • ***
  • Posts: 219
  • "It is not enough for code to work."
    • View Profile
    • http://www.morleydev.co.uk/
Re: Conditional C++11 Support
« Reply #8 on: July 06, 2014, 04:50:25 pm »
Yeah, I'm trying to avoid that (edited that post several times xD), but it's difficult to discuss the risks in both without mentioning the risk that it could be easier break something for only one compiler when supporting C++11. And that maybe at present there's not enough support for things like thread for a lot of the benefits people are talking about to actually be usable. In the future that may change.

So, essentially, the decision of conditional or unconditional to me seems to be based on how much of the kool-aid can we drink, or expect to drink? A light-weight touch could allow for unconditionalness (no move constructors or unique_ptr? 2008 called), but would make most of the benefits people talk about for going unconditional (std::thread, unicode literals) unusable without dropping support for various toolchains and it seems like most of those lightweight features are the easiest ones to make conditional.
« Last Edit: July 06, 2014, 05:02:16 pm by MorleyDev »
UnitTest11 - A unit testing library in C++ written to take advantage of C++11.

All code is guilty until proven innocent, unworthy until tested, and pointless without singular and well-defined purpose.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6286
  • Thor Developer
    • View Profile
    • Bromeon
Re: Conditional C++11 Support
« Reply #9 on: July 06, 2014, 04:57:20 pm »
It will make more sense to look at the specific C++11 features once we actually switch -- at that time, the world will look different, and compilers may support much more than today. And of course, the list of new language and library features that SFML will use is not definitive. So, let's not look at specific features and compilers in this thread -- after all, this is what eXpl0it3r explicitly asked for in his initial post.

It would be good to gather general points for or against a mandatory C++11 SFML. Since there have already been loads of arguments in favor of making C++11 unconditional, it would be interesting to see the other point of view.

That is, people who have justified reasons against mandatory C++11 (most probably professional developers bound to a specific environment), and how they imagine progress under that constraint.
« Last Edit: July 06, 2014, 04:59:00 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Hiura

  • SFML Team
  • Hero Member
  • *****
  • Posts: 4321
    • View Profile
    • Email
Re: Conditional C++11 Support
« Reply #10 on: July 06, 2014, 07:30:54 pm »
SFML 3 is obviously the future of SFML. However, this future won't happen overnight. Until it's ready we can expect a lot of things to change.

Having a conditional support will only slow us down beside making things more complicated for everybody else. If people need to stick with old compiler, then SFML 2.x (which is already a good product IMO) is the solution for them.

C++11 is already 3 years old and will be older when SFML 3.0 is released. I see no good argument to keep living in the past and not take advantage of the "new" features.
SFML / OS X developer

Jesper Juhl

  • Hero Member
  • *****
  • Posts: 1405
    • View Profile
    • Email
Re: Conditional C++11 Support
« Reply #11 on: July 10, 2014, 10:45:36 pm »
Should SFML implement conditional C++11 support?
If it can be done without too much trouble, then yes, why not?
If it is going to be too much of a pain to support and maintain, then don't bother. SFML is already perfectly usable in host projects written in pure C++11, so we can wait until SFML can go full-blown C++11 in 3.0 to reap the benefits then.
That's not to say that it wouldn't be nice to be able to enable a few C++11 features in SFML before 3.0, but it's not absolutely crucial.

Should SFML move to unconditional C++11 support at one point?
Yes!
There's no doubt in my mind about this one. C++11 is a (almost) a completely new language when compared to C++98/03 and it's a much better language. Of course SFML should adopt it. Here are some reasons (obviously incomplete list):
  • Getting "with the program" and adopting modern C++ is an important signal to send to both users and contributers that SFML is still a project that's alive and well.
  • Things like shared_ptr, unique_ptr, weak_ptr and move semantics make it so much easier to make the RAII argument. Which is a good thing.
  • Features like the range based for loop make code much more readable (and it can even be faster than traditional loops).
  • There are so many nice new algorithms, containers and more to take advantage of in the new standard library/STL, it would be a shame for SFML not to take advantage of them (just to mention a few: std::unordered_map, std::copy_n, std::thread, std::future, std::iota, std::function, std::to_string and much, much more).
  • Things like constexpr, static_assert, nullptr, override/final keywords, auto and decltype just make ones life much easier, less error prone, simpler and more readable.
  • Not having to declare function objects potentially a long way from where they are used and being able to just write a lambda directly where needed is so nice.
  • I'm sure move semantics with their potential performance improvement could be exploited in a few places within SFML for everyones gain.
  • Uniform initialization/Initializer lists could probably be used to simplify parts of the API.
In my opinion there's absolutely no reason not to adopt C++11 as much as possible as soon as possible. It's a much better language than C++98/03 ever was and it has so much potential to simplify the code, simplify the API and make it safer. It can provide some performance improvements if used correctly and - it's simply the future.

What feature should be considered for the conditional C++11 support?
If you want to keep it really simple, then just add a CMake switch to enable whatever compiler flags are needed (like std=c++11 for GCC and Clang) to enable C++11 features in the compiler while building SFML. Doing nothing else will at least let the compiler take advantage of C++11 support in the standard library parts that SFML uses internally and whatever other C++11 optimization tricks it may have up its sleeve. Doing nothing but this will provide some (arguably minor) improvements to people using a C++11 compiler with SFML and won't place any undue maintenance burden on the SFML team.

Going a bit further (still only considering conditional C++11 support, not what we'll hopefully have in 3.0); it would be nice if we could get applicable code marked with constexpr and maybe add override to all virtual functions. That should be doable with a bit of macro magic. Making all code that deals with null pointers use nullptr would also be nice and should again be fairly trivially doable conditionally. Proper marking of relevant functions with noexcept would also be nice. I guess it would also be reasonably simple to implement move constructors and move-assignment operators for classes where it makes sense and just conditionally leave them out in a C++98/03 build.
« Last Edit: July 10, 2014, 10:51:13 pm by Jesper Juhl »

Kojay

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Conditional C++11 Support
« Reply #12 on: July 11, 2014, 05:38:27 am »
If you want to keep it really simple, then just add a CMake switch to enable whatever compiler flags are needed (like std=c++11 for GCC and Clang) to enable C++11 features in the compiler while building SFML. Doing nothing else will at least let the compiler take advantage of C++11 support in the standard library parts that SFML uses internally and whatever other C++11 optimization tricks it may have up its sleeve. Doing nothing but this will provide some (arguably minor) improvements to people using a C++11 compiler with SFML and won't place any undue maintenance burden on the SFML team.

You can already add flags when configuring the CMake file. Compiling with C++11 should generate default move contructors wherever possible.

Cornstalks

  • Full Member
  • ***
  • Posts: 180
    • View Profile
    • My Website
Re: Conditional C++11 Support
« Reply #13 on: July 11, 2014, 07:33:06 am »
You can already add flags when configuring the CMake file. Compiling with C++11 should generate default move contructors wherever possible.

Although most of the classes in SFML have user-defined constructors, which means no other constructors are auto-generated (including move constructors).

Kojay

  • Full Member
  • ***
  • Posts: 104
    • View Profile
Re: Conditional C++11 Support
« Reply #14 on: July 11, 2014, 07:58:18 am »
User-defined copy constructors (which isn't the case to my knowledge)? Because otherwise it's not a problem.

See en.cppreference.com/w/cpp/language/move_constructor#Implicitly-declared_move_constructor
« Last Edit: July 11, 2014, 08:00:57 am by Kojay »