C++11 Adoption stance

Discussion area about developing or extending OGRE, adding plugins for it or building applications on it. No newbie questions please, use the Help forum for that.
qwertzui11
Halfling
Posts: 80
Joined: Wed May 14, 2008 10:44 am
Location: EU
x 22
Contact:

Re: C++11 Adoption stance

Post by qwertzui11 »

dark_sylinc wrote:In "large" projects with 15-20-minute compiling time being brought down to 8 minutes by just switching to a different compiler, your opinion will quickly change. Being able to test the code, iterate and debug faster is far more important than a couple of language additions that improve readability when used well.
I get your point, compilation time matters! But most the times you dont rebuild, or change a header like Vector3. There are optimisation tools like ccache for compilation speedup. This thread says C++11 compilation time seems to be bad for the old VS2012 compiler. There are a lot of compilers that dont suffer from that issue.

So I stick with +1 for some C++11 features :wink:
Zonder wrote:Sorry couldn't resist....
:twisted:

Markus
User avatar
TheOnlyJoey
Halfling
Posts: 53
Joined: Sun Apr 10, 2011 12:05 pm
Location: The Netherlands
x 6
Contact:

Re: C++11 Adoption stance

Post by TheOnlyJoey »

qwertzui11 wrote:
dark_sylinc wrote:In "large" projects with 15-20-minute compiling time being brought down to 8 minutes by just switching to a different compiler, your opinion will quickly change. Being able to test the code, iterate and debug faster is far more important than a couple of language additions that improve readability when used well.
I get your point, compilation time matters! But most the times you dont rebuild, or change a header like Vector3. There are optimisation tools like ccache for compilation speedup. This thread says C++11 compilation time seems to be bad for the old VS2012 compiler. There are a lot of compilers that dont suffer from that issue.

So I stick with +1 for some C++11 features :wink:
Zonder wrote:Sorry couldn't resist....
:twisted:

Markus
I am personally against the adoption of C++11 for quite a wide array of reasons.
In many projects I did with other company's I found out that there is a current trend of trying to fix things by using more abstraction or higher level solutions, while I think this is wrong.

The reason for me to use C++ is since it adds a lot of nice features on top of C, but you keep the opportunity to low-level optimise things.
Many of the new 'features' in modern C++ are still a lo more efficient when done with a low-level alternative.
I don't like the higher level focus and things like trying to introduce multi platform threading by adding it into the STL is a bad thing in my opinion, primarily because there always will be faster and more stable alternatives.
The test we have done internally always seem to be that pure C++11 applications are slower then C++ with low level optimizations.

I do get lambdas, those can be really useful (though they are really ugly imho) but I am not adopting something for 1 specific feature.
Also breaking c ABI more and more is a issue for me.

The compile time also is quite a big deal, specifically on bigger projects.
I have to say that GCC/mingw is not to bad with C++11 but the additional time literally takes hours away that could be spend on programming.
Avoiding VC is a good idea anyway when doing c++ imho.

If I would want to go more high level, I would adopt another language, these additions look way to sharp for me.
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: C++11 Adoption stance

Post by mkultra333 »

I have nothing serious to add. Just here to note with humour that Lambdas look like the horrible, hacky, cramped, complicated, hard to read code you used to get slapped across the head for by OO purists. The kind of thing I would use. I'll have to take a tutorial on them.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5292
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: C++11 Adoption stance

Post by dark_sylinc »

I tried Visual Studio 2015 Update 2 on Windows 10.

Pros:
  • Cold boot is faster from previous iterations.
  • Intellisense is much faster
  • Typing speed is better
Cons.
  • OgreMain (Release, v2.1) compiles in 2:29 in VS2008. In VS2015 Release takes 6:20 and Debug 4:30.
Looks like we're not dropping VS2008 support anytime soon. I applaud the improvements, but iteration time is essential.
qwertzui11
Halfling
Posts: 80
Joined: Wed May 14, 2008 10:44 am
Location: EU
x 22
Contact:

Re: C++11 Adoption stance

Post by qwertzui11 »

dark_sylinc wrote:
qwertzui11 wrote:- threading
Standard-lib threading has no place in a high performance graphics engine.
never got that argument. What exactly is so slow about stl::thread? The creation? okay - but we only create once and reuse the thread? Or do u mean things like std::mutex and atomics?
dark_sylinc wrote:
qwertzui11 wrote:- range based iteration http://en.cppreference.com/w/cpp/language/range-for
I'm personally against these type of for idiom. I would have to sit down to write down and remember all the things I don't like about that expression. It has enough drawbacks I don't like.
there r some great upsides.
http://stackoverflow.com/questions/1082 ... erformance
eg. that ::end() doesn't get called every iteration --> depending on container, performance improvement.
But I'm here to learn, pls correct me :wink:
dark_sylinc wrote:
qwertzui11 wrote:Compile time, shouldn't be an argument for using C++11.
In "large" projects with 15-20-minute compiling time being brought down to 8 minutes by just switching to a different compiler, your opinion will quickly change. Being able to test the code, iterate and debug faster is far more important than a couple of language additions that improve readability when used well.
Particularly in game development, which by nature is all about reducing iteration times as much as possible.
I personally am a huge fan of boost, especially asio, signals2, files_system, iostream... (in the latest beta it even has a lib to ease up openCL) . These header only libraries slow down your project-compilation a lot, even if you use clang. But I just hate to reinvent the wheel, I got better things to do in life :wink: So I know quite well what you mean. However recompilation happen rarely and if they do, there are great tools to improve the speed. eg. ccache https://ccache.samba.org/
Seems like in C++20 there will be modules which should reduce compilation time a lot.

Imho the language feature advantages win, because ur talking about recompilation. But seems like Ogre 2.* doesn't drop some legacy stuff, which is fine. Visual Studio 2008 support? really??? I get it for 1.* but 2.*??? :roll: :oops:
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5292
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: C++11 Adoption stance

Post by dark_sylinc »

never got that argument. What exactly is so slow about stl::thread? The creation? okay - but we only create once and reuse the thread? Or do u mean things like std::mutex and atomics?
I meant the whole package (mutex, atomics, chrono)
But even then, std::thread results in garbage overhead around the function caused by the template, unless the compiler is really, really, really, really good at optimizing it. Which can't beat a C call. Literally, setting up the stack for passing arcuments, and a call instruction.
Furthermore, we don't know what happens in std::thread. It may keep a pool inside of running threads for example. We don't want unknowns.
Another problem is that it tends to make callstacks cryptic.
there r some great upsides.
http://stackoverflow.com/questions/1082 ... erformance
eg. that ::end() doesn't get called every iteration --> depending on container, performance improvement.
But I'm here to learn, pls correct me :wink:
Which... are completely avoidable if you write non-idiotic loops in the first place.
There is a reason I write my loops like this:

Code: Select all

vector<int>::const_iterator itor = container.begin();
vector<int>::const_iterator end  = container.end();
while( itor != end )
{
	++itor;
}
Simple, expressive, optimized.
Nothing's worse than having a crash inside the code automatically-generated by a range-for because you've invalidated the iterators by accident. It's much better if it crashes in one of your lines (quite obvious to spot when itor or end got corrupted).
Imho the language feature advantages win, because ur talking about recompilation. But seems like Ogre 2.* doesn't drop some legacy stuff, which is fine. Visual Studio 2008 support? really??? I get it for 1.* but 2.*???
There's nothing about legacy in Visual Studio 2008. It still remains as the best Visual Studio released to date. The C++11/17 features are nice to have but nothing I miss, they provide marginal benefits save for very exceptional cases.

Develop on VS2008, deploy with VS2013/2015 for the most optimized generated code.
I can't stress enough:
BUILD TIMES AKA ITERATION TIMES ARE ONE OF THE MOST IMPORTANT THINGS IN DEVELOPMENT.
That alone puts VS2008 far above the other Visual Studios. I hope Microsoft hurries up and finishes Clang for Windows. Hopefully that will get the fastest build times on Windows.

As for C++ features, modules is something I've been keeping my eye... for a very long time. I'll believe it when it arrives. The C++ comitee has lately been having a habit of introducing completely useless or barely useful features while neglecting long-standing issues (except std::extent, which is cool and actually solves one of the problems mentioned there, but for some reason std::extent is largely absent from most lists of advertised new features).
But oh well, I'm more aligned with the principles of Orthodox C++ kind of guy.
I personally am a huge fan of boost, especially asio, signals2, files_system, iostream... (in the latest beta it even has a lib to ease up openCL) . These header only libraries slow down your project-compilation a lot, even if you use clang. But I just hate to reinvent the wheel, I got better things to do in life :wink:
Well, unless it's a very small project (i.e. standalone command line tools with <2000 loc or so); time and again experience proves me we lose far more time in aggregated build times than we do from just writing the functionality myself. None of those boost libraries you mentioned are rocket science, and that code can be reused across your projects once written.
files_system is the nicest one of the bunch, /ranton while Asio is extremely over-engineered and complicated. Having written network libraries using posix sockets, libevent, Python sockets, RakNet, and Asio; Asio has been the most overly complex Rube-Goldberg machines of them all. It just forces templates into something that never needed it, and makes it significantly harder to deal with, because modularity and isolation goes to hell as the TCP listener needs to be aware of the TCP socket, the endpoints, the receiver and the sender just because the compiler can't compile without everything otherwise.
I was shocked when Asio ended up included in Boost. I was like... "waat?"
Asio fails to complain with basic Object Oriented theory such as reusability, modularity and isolation, which is supposedly the point of Boost. /rantoff
qwertzui11
Halfling
Posts: 80
Joined: Wed May 14, 2008 10:44 am
Location: EU
x 22
Contact:

Re: C++11 Adoption stance

Post by qwertzui11 »

dark_sylinc wrote:Which... are completely avoidable if you write non-idiotic loops in the first place.
There is a reason I write my loops like this:

Code: Select all

vector<int>::const_iterator itor = container.begin();
vector<int>::const_iterator end  = container.end();
while( itor != end )
{
	++itor;
}
Simple, expressive, optimized.
Nothing's worse than having a crash inside the code automatically-generated by a range-for because you've invalidated the iterators by accident. It's much better if it crashes in one of your lines (quite obvious to spot when itor or end got corrupted).
wow - you really call that better than c++11 range based loops - just wow
dark_sylinc wrote: There's nothing about legacy in Visual Studio 2008. It still remains as the best Visual Studio released to date. The C++11/17 features are nice to have but nothing I miss, they provide marginal benefits save for very exceptional cases.
OT: That's just sad. Bu I get why developers working with Microsoft products have to say that. I'm happy about the fact, that MS is rethinking their C++ strategy and times are getting better.
dark_sylinc wrote: Well, unless it's a very small project (i.e. standalone command line tools with <2000 loc or so); time and again experience proves me we lose far more time in aggregated build times than we do from just writing the functionality myself. None of those boost libraries you mentioned are rocket science, and that code can be reused across your projects once written.
files_system is the nicest one of the bunch, /ranton while Asio is extremely over-engineered and complicated. Having written network libraries using posix sockets, libevent, Python sockets, RakNet, and Asio; Asio has been the most overly complex Rube-Goldberg machines of them all. It just forces templates into something that never needed it, and makes it significantly harder to deal with, because modularity and isolation goes to hell as the TCP listener needs to be aware of the TCP socket, the endpoints, the receiver and the sender just because the compiler can't compile without everything otherwise.
I was shocked when Asio ended up included in Boost. I was like... "waat?"
Asio fails to complain with basic Object Oriented theory such as reusability, modularity and isolation, which is supposedly the point of Boost. /rantoff
I just hate it when companies deliver their own string/vector/network class. U can't google issues. Often these classes are terrible documentated. These devs believe they can achieve better results. And they do, in their specific tests. But most of the times they fail in overall performance.
Asio: yes that library got its problems and only will get 90% percent of the performance of a specific problem. But that library safes a LOT of time, when it comes, eg., to platform independency. Beside, lots of people use it, so'll find other great network libraries working with it. In example websockets, http server, REST interfaces... out of the box.
imo lots of C++-Developer fail to implement features, instead they implement basic stuff, break compatibility, make it unusable and waste so much time :/

I remember times when Ogre had its custom strings and arrays - just awful to work with
qwertzui11
Halfling
Posts: 80
Joined: Wed May 14, 2008 10:44 am
Location: EU
x 22
Contact:

Re: C++11 Adoption stance

Post by qwertzui11 »

if u develop everything on ur own u can't use other open source libraries. Or worse u start casting everything :roll:
Despite that, u stop going with the times and become an "old dev" :D
User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 138

Re: C++11 Adoption stance

Post by c6burns »

qwertzui11 wrote:I just hate it when companies deliver their own string/vector/network class
I get what you are saying, but the flipside of that coin is:
I hate it when every platform ships with its own implementation of the standard libraries which could have different behaviour from my other platforms. For example, issues can often arise where it becomes difficult for you to control when container allocations occur (which directly determine the container's usefulness in a real time application), not to mention how frustrating STL allocators can be :lol: It's no wonder companies like EA invest so heavily into things like EAstdC and EASTL
qwertzui11
Halfling
Posts: 80
Joined: Wed May 14, 2008 10:44 am
Location: EU
x 22
Contact:

Re: C++11 Adoption stance

Post by qwertzui11 »

c6burns wrote:I hate it when every platform ships with its own implementation of the standard libraries which could have different behaviour from my other platforms.
Most STL implementations are "quite stable". There will be way more bugs in your own implementation. And again, if u got an issue with a library lots of people use, u r not the first dealing with the same issue.
Besides I'm developing with the STL for nearly 10 years on nearly all platforms with different architectures. Never had any issues. Can't say that about "windows.h" :lol:
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: C++11 Adoption stance

Post by mkultra333 »

I"ve just switched over to using VS2013, from years of VS2008. I thought it would be better but I'm not a fan, it's slower to compile which is super painful during bug hunts, and the basic search functions don't seem to work as expected. On my laptop, which I use a lot, the editor is laggy. For my main project I'm tempted to go back to VS2008 for general programming and only use VS2013 for releases, like dark_sylinc is apparently doing for Ogre.

VS2015 wouldn't install, it kept freezing midway, I suspect while trying to download Android components. The ISO doesn't work either, it still requires online downloading.

I have an aversion to the newest, shiniest thing. Be it an OS, a phone, a development environment. Most the time, you don't need them. Half the time, they're worse than what you had, at least at first. If you don't need to update, you need to not update.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 138

Re: C++11 Adoption stance

Post by c6burns »

qwertzui11 wrote:
c6burns wrote:I hate it when every platform ships with its own implementation of the standard libraries which could have different behaviour from my other platforms.
Most STL implementations are "quite stable". There will be way more bugs in your own implementation. And again, if u got an issue with a library lots of people use, u r not the first dealing with the same issue.
Besides I'm developing with the STL for nearly 10 years on nearly all platforms with different architectures. Never had any issues. Can't say that about "windows.h" :lol:
What I am trying to explain is that since the standard leaves allocation up to the implementation, you don't necessarily have consistency when deploying multi-platform. It can all be perfectly stable, but different platforms are going to allocate at different times, or under different conditions. For some applications that is unacceptable, performance-wise. If your application is not that performant, and you "never had any issues" then that's great for you. But, as an example, EA developed their own STL and published papers on why. No offense, but I'm guessing EA's work exposed more of the performance/useability issues of the various STL implementations than your own. They aren't just over-engineering. Another example would be Crytek using stlport. Also think about console platforms ... do you want to have to care how Sony implemented their containers across multiple platforms?

Anyway we are off on a bit of a tangent, but the point I am making is that while it may be annoying, there can be concrete reasons to implement your own cross platform code - even for something as simple as containers - and there are various examples of this within the industry. And of course things do change ... 15 years ago we wouldn't even be having this conversation. We would unquestionably not be using the standard :lol: so yes things get better over time, and situations can be re-evaluated :)
qwertzui11
Halfling
Posts: 80
Joined: Wed May 14, 2008 10:44 am
Location: EU
x 22
Contact:

Re: C++11 Adoption stance

Post by qwertzui11 »

c6burns wrote:Anyway we are off on a bit of a tangent, but the point I am making is that while it may be annoying, there can be concrete reasons to implement your own cross platform code - even for something as simple as containers - and there are various examples of this within the industry. And of course things do change ... 15 years ago we wouldn't even be having this conversation. We would unquestionably not be using the standard :lol: so yes things get better over time, and situations can be re-evaluated :)
we agree :wink: the STL is full of annoying legacy stuff... eg. std function is just broken / misdesigend :/
To get back to topic, C++11 standard is 5 years old. Bjarne Stroustrup said "it feels like a new language" and I agree. For Ogre 2.* I'd love to see it. But in the end of the day it doesn't really matter. And because I'm not a contributor I shouldn't annoy u too much about it :D
User avatar
mkultra333
Gold Sponsor
Gold Sponsor
Posts: 1894
Joined: Sun Mar 08, 2009 5:25 am
x 114

Re: C++11 Adoption stance

Post by mkultra333 »

I bet 5 years seems like a long time to some people.

I've been working on my current Ogre project for 7 years.
"In theory there is no difference between practice and theory. In practice, there is." - Psychology Textbook.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5292
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: C++11 Adoption stance

Post by dark_sylinc »

wow - you really call that better than c++11 range based loops - just wow
Yes. I actually believe that. When you've got dealt with a fair share of bugs caused by yourself, caused by external libraries, caused by the compiler, caused by hardware errors, caused by weird garbage collector behaviors (i.e. when interacting C++ with C#), caused by driver errors, caused by OS errors... you learn to appreciate the beauty of a loop in 4 lines:
  • container.begin() can fail (container's bad).
  • vector<T>::const_iterator itor = container.begin() can fail (vector<T> and the container's type matched at compile time but they don't match at runtime, likely DLL hell, but not the only explanation).
  • container.end() can fail.
  • vector<T>::const_iterator end = container.end() can fail.
  • while( itor != end ) can fail.
  • *itor can fail.
  • ++itor can fail.
Now condense that into ranged for, a single line of code, where all of those multiple failure points (which aren't mutually exclusive) are hidden behind compiler-generated code. Debugging that is a nightmare, because you have to look at the assembly of code you didn't write (which I often do, but I'd like to prevent if possible).

Modern C++ features seem to be focused around typing speed. That is hardly the limitation factor when developing code. I don't save much time from typing that while loop by typing a ranged for. I do, but it's not much. But I do save a lot more time when the loop crashes and I need to debug it.
Furthermore if I later need to add a second condition to the loop, I then need to remove the ranged-for loop and convert it to a regular one.

If you think this is harsh, you should look at Nasa's coding guidelines for mission critical flight software.

If you think these edge cases won't happen to you... well they happen to me. And quite often. Just 6 days ago I filled a bug report regression to Apple where the latest XCode 7.3 compiled iOS code incorrectly crashing inside the initialization of constant global variables (__cxx_global_var_init). std::vector was involved btw.
I had to change our code just to workaround the compiler bug.
So yeah, I'll take my 4-line loop any day over a ranged-for loop.
I just hate it when companies deliver their own string/vector/network class
I get what you are saying, but the flipside of that coin is:
I hate it when every platform ships with its own implementation of the standard libraries which could have different behaviour from my other platforms.
Indeed. Diverging behavior causes a lot headaches when you're writing a library that targets Windows, Linux, OS X, iOS, Android & Windows Phone.
One of the things I like about std::vector is that you get a lot of sweet functionality, grab a pointer to its internal data and treat it like a raw pointer. But even then, there are edge cases where std::vector could eat a lot of performance in some, but not all, of the implementations.
This is the reason I wrote "Ogre::FastArray". It's a replacement for std::vector in critical paths. FastArray behaves the same way in all platforms and has a very well known behavior with little hidden surprises. But it's not a container to be used everywhere. Try using it in complex non-POD datatypes and it may crash.
I could bring more examples but I don't have the whole day.
I just hate it when companies deliver their own string/vector/network class. U can't google issues. Often these classes are terrible documentated. These devs believe they can achieve better results. And they do, in their specific tests. But most of the times they fail in overall performance.
Honestly I rarely see they fail in overall performance. Writing your own std replacement that outperforms the standard std::map for example is quite easy.

But scratch that. Because often we wouldn't use std::map in performance critical paths, and like you said, writing your own does indeed come with a bag of potential bugs in the implementation (which translates to lost development time and frustration).
What I see is a difference in phylosophy. When you say "U can't google issues" (which is good to be able to google issues) I say "yay, I can step inside and see what's going wrong. Heck I may even be able to fix it!". My first reaction "step inside, then use google". If I step inside and see it's a complex trainweck, then perhaps I should reconsider my choice of libraries.

std::string is another class I like. Quite easy to use, and string manipulation can be very difficult. Its performance sucks (it's filled with reallocations), but it's great for dealing with logging or user interaction.

I don't like reinventing the wheel either. The thing is, boost isn't a wheel. It's a decagon that happens to roll enough to get things moving, but it drags like hell.
I would choose libevent a billion times over Asio for example, libevent is a great example of a library I would use over handrolling my own. It's small, simple, efficient, portable, and popular.
std::vector is nice, std::string is nice. std::map & std::set are useful but if avoidable then better. std::find is great, std::lower_bound is great. std::sort is very useful.
We move outside these functions and we enter controversial territory. Heck, I had to write our own Ogre::min and Ogre::max for floating point (literally one minss and maxss instruction) because std::min & std::max were generating horribly bad code.
mkultra333 wrote:VS2015 wouldn't install, it kept freezing midway, I suspect while trying to download Android components. The ISO doesn't work either, it still requires online downloading.
That's sad. I installed VS2015 without Android components (I plan on installing that later), so far I'm much more happy with VS2015 than 2013; particularly when it comes to UI responsiveness. That is a huge win in my book. Build times didn't seem to have improved much though.
paroj
OGRE Team Member
OGRE Team Member
Posts: 1993
Joined: Sun Mar 30, 2014 2:51 pm
x 1073
Contact:

Re: C++11 Adoption stance

Post by paroj »

dark_sylinc wrote: Yes. I actually believe that. When you've got dealt with a fair share of bugs caused by yourself, caused by external libraries, caused by the compiler, caused by hardware errors, caused by weird garbage collector behaviors (i.e. when interacting C++ with C#), caused by driver errors, caused by OS errors... you learn to appreciate the beauty of a loop in 4 lines:
If your OS and your hardware is failing you probably have bigger problems than not knowing why your loop crashes. The same goes if the OS behaves differently than what you expect because your are constantly writing broken code then.

If you are writing flight software where you have to deal with random bitflips in memory a 4 line loop header might have its uses, but this is not the typical use of Ogre. And you should aim for the common case.
dark_sylinc wrote: Modern C++ features seem to be focused around typing speed. That is hardly the limitation factor when developing code. I don't save much time from typing that while loop by typing a ranged for. I do, but it's not much. But I do save a lot more time when the loop crashes and I need to debug it.
The more you have to type the more can go wrong: "vector<T>::const_iterator end = container.begin()". Actually this is not really about typing speed but about reading speed. If somebody has to read code where 90% is boilerplate, he never will see any bugs in the boilerplate part. This is about understanding code that you did not write.
dark_sylinc wrote: Debugging that is a nightmare, because you have to look at the assembly of code you didn't write (which I often do, but I'd like to prevent if possible).
this is NIH. If I have to debug your code, I did not write it either. And chances are much higher that I already debugged std::vector before than that I debugged Ogre::FastArray.
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5292
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: C++11 Adoption stance

Post by dark_sylinc »

paroj wrote:If your OS and your hardware is failing you probably have bigger problems than not knowing why your loop crashes. The same goes if the OS behaves differently than what you expect because your are constantly writing broken code then.
But you've got to recognize those problems first. And becomes easier.

Btw problems that can be caused by the OS that are perfectly valid and I've encountered:
  • DLL missmatch.
  • Shared library installation problems.
  • Security updates that broke everyone's code.
  • LD_LIBRARY_PATH problems.
  • Leaks.
  • Out of memory.
  • Process termination (iOS & Android, I'm looking at thee).
  • Corruption caused by incorrect context switching.
  • Debugging problems.
Problems caused by hardware that aren't subject for buying a new system and that I've encountered:
  • Floating point non-determinism (like in the infamous fdiv bug, but far more subtle and far less popular).
  • Failure to raise an exception during an operation that should've raised an exception (e.g. integer division by zero). Try looping with "% variable", variable becoming 0, and have some random PC actually not crash (granted, my mistake for not checking 'variable' could be 0, but machines that misbehave on this can add a lot of confusion).
  • Alignment issues (platform specific, caused by the developer's code, but some HW masks the problems, others die spot on).
  • Bus garbage or bus lock problems when reading from GPU.
  • Infinite loops because of sending wrong data to the GPU (system freeze on Linux, TDR on Windows).
  • DDR3 row hammering.
  • System corruption when saturating bus bandwidth (happens more common than you think on expensive laptops)
None of these problems are major reasons for buying new hardware, or having "bigger issues than my program", or it may be major reasons but are present in a lot of computers (i.e. row hammering).
This is my every day work. I find HW & OS bugs more frequently than you think. It's not like it's raining these bugs, but it's enough for having thank myself several times for writing loops like that.
paroj wrote:The more you have to type the more can go wrong: "vector<T>::const_iterator end = container.begin()". Actually this is not really about typing speed but about reading speed. If somebody has to read code where 90% is boilerplate, he never will see any bugs in the boilerplate part. This is about understanding code that you did not write.
I hardly consider that boiler plate. See the auto discussion above.
That line is telling me it's an iterator to T, that can't be modified because it's const, stored in a vector (hence contiguous memory); and that has a bug because end = container.begin() instead of end = container.end().
Something that is much easier to catch in context:

Code: Select all

vector<T>::const_iterator itor = container.begin();
vector<T>::const_iterator end  = container.end();
vs

Code: Select all

vector<T>::const_iterator itor = container.begin();
vector<T>::const_iterator end  = container.begin();
I always leave two spaces between 'end' and '=' so that both lines align; and this miss-match becomes easy to spot. The second line must always be one character shorter than the first one.
It only works on fixed-length fonts though.
paroj wrote: this is NIH. If I have to debug your code, I did not write it either. And chances are much higher that I already debugged std::vector before than that I debugged Ogre::FastArray.
Oh, you're completely right about that. I try to use FastArray sparingly, where performance is critical and obliterates everything else.
User avatar
MadWatch
Halfling
Posts: 64
Joined: Sat Jul 06, 2013 11:25 am
x 4

Re: C++11 Adoption stance

Post by MadWatch »

Just out of curiosity, I've been told that the use of exceptions and RTTI is forbidden, or at least discouraged, on console and mobile platforms. I never did any console or mobile development myself so I don't know how true this statement is. But assuming it is true, then shouldn't Ogre completely give up on both STL and Boost (which both make heavy use of exceptions) if it is to be ported on these platforms ?
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5292
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: C++11 Adoption stance

Post by dark_sylinc »

MadWatch wrote:Just out of curiosity, I've been told that the use of exceptions and RTTI is forbidden, or at least discouraged, on console and mobile platforms.
It's forbidden in the sense that adding exceptions or RTTI to an existing codebase "may get you fired", very strongly discouraged is the word. Note not all dev. companies are like that. Some don't care, or are willing to assume the cost to cut dev time (e.g. including 3rd party libraries that require it). It's one of the reasons the stb family is so popular among gamedevs.
Though some platforms literally don't support them. IIRC Android didn't support them for a long time, but that's thing of the past now.
Current-gen consoles are x86 machines with 8GB RAM, so that ain't a technical problem either now.
MadWatch wrote:shouldn't Ogre completely give up on (...) Boost (which both make heavy use of exceptions) if it is to be ported on these platforms ?
Using Boost "may definitely get you fired", unless you're using it in an offline tool.
MadWatch wrote:But assuming it is true, then shouldn't Ogre completely give up on both STL and Boost (which both make heavy use of exceptions) if it is to be ported on these platforms ?
On these platforms where Exceptions/RTTI have scarce support, or where dev. practices "very strongly discourage" their use, they use compiler flags that disable these language features and have (usually vendor provided) STL implementations that are exception-free or with defined macros that disable the exception. Usually this leaves out non-basic STL templates outside std::vector list set & map.
But you're right that Ogre relies on RTTI/Exceptions too much (we throw to signal user errors FFS) which is the reason some console devs decided not to use Ogre in the past.

But fixing that... it would just be easier to start another engine from scratch. But I'm trying to prevent aggravating our reliance on RTTI/exceptions (*). Fortunately consoles and phones have become powerful, and in our current state (2.1) we're much faster & lighter than other popular alternatives (UE4, Unity) so, basically we just have to outrun the other guys when the bear is chasing you.

(*)I use asserts more often to signal user errors instead of throwing. But I still use throws when the error could easily have come from art-user error (i.e. incorrectly written material script) since it's more handy to look at the Ogre.log than a cryptic assert where you may need to hook the debugger. It keeps consistency with how Ogre always did things (and keeps doing things); and this obsession for lack of RTTI/exceptions can't introduce obvious usability & friendliness regressions.
User avatar
c6burns
Beholder
Posts: 1512
Joined: Fri Feb 22, 2013 4:44 am
Location: Deep behind enemy lines
x 138

Re: C++11 Adoption stance

Post by c6burns »

dark_sylinc wrote:IIRC Android didn't support them for a long time, but that's thing of the past now.
Totally correct, RTTI and exceptions were added

Like dark_sylinc said it really depends where you work. Some games are so performant that literally nothing is overlooked (think God of War or Last Of Us ... something exclusive to a single platform, optimized to near perfection, and exhibiting the absolute state-of-the-art for game development at the time of release). Not understanding the effects of RTTI and exceptions on generated code would be unacceptable when working on such a project ... that is why you would lose your job. Everyone would say "Woah I though they knew X, Y or Z about the compiler, how did they get this far in the job?". Most projects are not necessarily in that situation ... you will be fine trading man hours for a bit of performance loss on many if not most projects which is where this continuous confusion comes from outside the AAA dev circles: eg. why is STL bad it seems solid/reliable/fast to me? Why are exceptions bad, they solve some of my problems and seem fast enough for me? etc etc

I totally agree there's no cutting exceptions out of this codebase at this point, and most users won't even require (or notice) the gains from that anyway.

PS - I won't even use boost in tools ... I can't abide that f!@#$cking build system </rant>
paroj
OGRE Team Member
OGRE Team Member
Posts: 1993
Joined: Sun Mar 30, 2014 2:51 pm
x 1073
Contact:

Re: C++11 Adoption stance

Post by paroj »

http://llvm.org/docs/CodingStandards.html is an interesting read. Regarding C++11 features as well as RTTI.
noorus
Halfling
Posts: 75
Joined: Wed Apr 20, 2011 9:55 pm
Location: Helsinki, Finland
x 3

Re: C++11 Adoption stance

Post by noorus »

Quite a masturbatory practice, all the wrangling about these different strict subsets of C++ that even have their own names..
Personally I'm mostly with the camp of "C+", since we're talking about a language that's still supposedly close to the hardware, yet OO. If functionalism, automated memory handling, automated parallelism and lord knows what kind of type swizzling is your thing, then maybe just code haskell or javascript instead.

But there's a couple things I would never, ever give up: (multiple) inheritance, vftables, and exceptions. Banning any of them outright honestly seems unbelievably stupid.
If you're a C++ programmer, then you're a programmer with a good grasp of how all of these features relate to the eventual x86/x64 assembly. It comes with the territory.
If something needs to be truly performant, you don't virtualize it. Same goes for constant small heap allocations, for example. And you don't constantly pass around massive blobs of data by communicating with exceptions.

Exceptions, most of all, I think are the very definitive feature of C++. If you're not using exceptions, you're essentially using C, and honestly I have no idea why anyone would want to - unless you're working in the very guts of the kernel at ring 0, where graceful unwinding is simply impossible, or an embedded platform where there is nothing below, before or after your code. I'd rather slit my wrists than ever go back to returning guess-whatever-this-is special int values to signal something went to shit, and then having to propagate that back manually through the callstack. Gives me shivers, and I'm seriously thankful OGRE is at least not considering abandoning exceptions.

As for the complains about Visual Studio & Intellisense... I seriously hope all of you are using Visual Assist, right? Right..?
I find VS2015 absolutely great, IDE-performance wise. It's actually certainly faster than 2008 was on my rig.

The compiler performance argument is actually a valid one, but enabling minimal rebuild & linkage helps immensely - and I also like to think that I'm still processing something code-related in my mind while compiling, not swordfighting on office chairs.
But the recent possiblity of switching to Clang inside VS should, I imagine, solve all the compiler worries soon enough. Personally I haven't done it, though, I'm pretty happy and familiar with Microsoft's.
Creator of Nice Input Library, for your advanced input needs.
Image
noorus
Halfling
Posts: 75
Joined: Wed Apr 20, 2011 9:55 pm
Location: Helsinki, Finland
x 3

Re: C++11 Adoption stance

Post by noorus »

dark_sylinc wrote: That line is telling me it's an iterator to T, that can't be modified because it's const, stored in a vector (hence contiguous memory); and that has a bug because end = container.begin() instead of end = container.end().
Something that is much easier to catch in context:

Code: Select all

vector<T>::const_iterator itor = container.begin();
vector<T>::const_iterator end  = container.end();
vs

Code: Select all

vector<T>::const_iterator itor = container.begin();
vector<T>::const_iterator end  = container.begin();
I always leave two spaces between 'end' and '=' so that both lines align; and this miss-match becomes easy to spot. The second line must always be one character shorter than the first one.
It only works on fixed-length fonts though.
I have to admire your dedication to writing excruciatingly self-descriptive code, but on the issue of auto in C++11, I'd side with Enhex's arguments.
Firstly: typing speed actually does suffer, despite autocompletion - or suggestions, rather. The IDE has no idea you're going be assigning container.begin() to itor until you get to that part of the line, and by then you've already had to type out the class/namespace and iterator type. In reality this would of course be shorter by using typedefs, but then you might end up creating typedefs that are only ever needed a couple of times (in which case it's rather unnecessary clutter in the scope), and it's still going to be more verbose than auto.

Second: auto makes refactoring faster, and it's not a bad thing. If you start returning something fundamentally incompatible from a previously defined function, then it should probably not be the same function at all. And in any case, should you make such a mistake, it should be trivially caught by unit testing.

Third: Apart from the writing speed, I find that this level of verbosity actually hurts readability even more. When skimming through code, we're just not wired to mentally parsing such complex declarations very fast - and for a quick overview of what I'm looking at, I really don't care that the exact type here is vector<T>::const_iterator, since I can infer that it's an iterator very fast from the container.begin() and move on.
And when I find what I'm looking for and actually start looking closer at a specific part of code, I will be doing the hovering to examine exact types, as well as class or function prototypes and documentation, and it's no trouble at all, since figuring out the code and what to do to it is taking a much longer time than the hovering anyway.
Also, you can decorate the auto with const as well, so you know you're getting the const iterator and also seeing it without the infamous hovering.

Btw, casting stuff is one frequent case where there's absolutely no reason not to use auto.

Code: Select all

// if i'm casting something and assigning it to a variable, I already know exactly what the type is, from the very same line:
auto xboxController = (Device::XBoxController*)genericController;
// this, on the other hand, used to be a huge annoying waste of time:
Device::XBoxController* xboxController = (Device::XBoxController*)genericController;
Of course, like with all things C++, auto just has to be used intelligently.
Creator of Nice Input Library, for your advanced input needs.
Image
paroj
OGRE Team Member
OGRE Team Member
Posts: 1993
Joined: Sun Mar 30, 2014 2:51 pm
x 1073
Contact:

Re: C++11 Adoption stance

Post by paroj »

Ogre 1.x will switch to C++11 with 1.11, see http://www.ogre3d.org/2017/09/02/ogre-1 ... erm-report
qwertzui11
Halfling
Posts: 80
Joined: Wed May 14, 2008 10:44 am
Location: EU
x 22
Contact:

Re: C++11 Adoption stance

Post by qwertzui11 »

why not c++14?
which in my opinion is a "fixed c++11". eg. std::make_unique, improved and releaxed lambdas, releaxed constexpr and more
Post Reply