9 ms·
I've been engineering videogames in C++ for almost 20years working on AAA games and I can tell you that modern C++ is not very appealing to the vast majority of
by zonovar 4y ago
I've been engineering videogames in C++ for almost 20years working on AAA games and I can tell you that modern C++ is not very appealing to the vast majority of our industry. Modern C++ it's overcomplicated and from what I can see all the best software engineers I met in my careen write very simple C++98 code, maybe a bit of C++11 but that's it. They keep it simple. They don't need a move constructor because they've been already clever enough to solve a prolbem from a different angle. Modern C++ is for experienced C++ developers and it's solving problems that experienced developers know already how to solve without all this extra complexity. And because of that it's keeping away young developers...
This new C++ syntax is just a gimmick that we don't need. The C++ community seems it's feeding itself to create a new standard every couple of years. It's just disappointing...
- b20000 4y agoand that is why rust is bad. it solves problems for you, just like modern c++ tries to do. whereas these problens need to first be intimately understood by the engineer, before they can be solved. otherwise you will be faced with lots of unexpected surprises down the line.
- shakow 4y agoI hope you don't forget to prove the whole theory of integration whenever you are doing an FFT.
- TillE 4y agoC++98 is an miserable language, I have no idea who would actually be resistant to improving it. I fucking hated it, C++14 and beyond are such a relief. Move semantics aren't fun but they are necessary. This kind of claim is extremely common HN but utterly foreign as someone who actually writes C++ for a living.
- bb88 4y agoJava was a reaction to C++. Go was too. C++ feels like it was created by the smartest person in the room without regards for the the other 80% that would use it on a day to day basis. I guess that's why I like simpler languages more, where I don't have to think about how the language or compiler is going to treat my code.
- hedora 4y agoRust was also a reaction to C++, and is a move in the opposite direction as go. Go is OK. It's a little faster to get a first version working, but the result tends to be slower and more likely to crash on memory/concurrency issues than a rust version would be. I use both; go is fine for spaghetti ~architecting~ devops-ing piles of microservices together. Rust is much better for the data path though.
- bb88 4y agoHow do you like Rust for say SaaS type services? JSON marshalling/unmarshalling, socket behavior, etc? HTTP request/response processing? I spent the last two months coding in Go pretty much not enjoying it. Nil is not always equal to nil in third party libraries through an interface -- and the compiler wouldn't warn about it.
- leshow 4y agoNot OP, but if you have gripes about type safety, you're likely to enjoy rust. The compiler will absolutely let you know if you are not handling optional or result types. As a bonus, they are built using regular generic and enum constructs with a little bit of syntax sugar to make them more ergonomic. serde is also world class for serializing/deserializing, and can generate implementations for you based on struct definitions independent of data format (json/bson/yaml/toml/etc). The only sharp edge you may bump into for a web service is in your choice to go either sync or async, and if you go async you must then choose a runtime (usually tokio) as these are libraries and not integrated into the std lib beyond just the `async` keyword and a few traits.
- sph 4y agoMy hopes for Rust is that they take their async coloured functions back to the drawing board because they are really not fun to deal with, and improve the FFI story with C. Easy interface with C and it's weird memory rules is of utmost importance if we want to replace C with something a little more solid. But yeah, serialization in Rust is a breeze compared to Go. Probably one of the things I hated the most, along with the errnil boilerplate.
- lifthrasiir 4y agoI have too written C++ for years---I worked on online game server frameworks---and you are partially right, C++98 is not for mere mortals, but we still tended to use only a part of C++11 and C++14 we saw fit. This is the point: not every new C++ feature is relevant to at least some of us, and the relevant fraction is ever diminishing.
- bb88 4y agoC++98 is the reason Java came to power.
- rramadass 4y agoNo; Java's success is entirely due to Marketing.
- bb88 4y agoOh no. I was there. Cross platform C++ was hard. Cross platform Java was easy.
- rramadass 4y agoThat wasn't it; There was nothing revolutionary about it. It was the most hyped/marketed language in History[1]. Sun threw ungodly amounts of money to market it and make it what it is today. Invented as a "Embedded Systems" language, pushed as a Browser "Applet" language, moved to "Server App" language and settled as a "Enterprise App" language. [1] https://www.theregister.com/2003/06/09/sun_preps_500m_java_brand/ https://www.theregister.com/2003/06/09/sun_preps_500m_java_b...
- enjoy-your-stay 4y agoI think the fact that it eventually ended up as a server app language took everybody by surprise - Sun never saw it as anything like that at inception I'm sure. Adding JDBC and later nio is probably what got it there the most.
- bmitc 4y agoThe fact that these standards (?) or versions (?) of C++ are so wildly different to summon these types of opinions is mind blowing to me. I like languages like F#, Elixir, Erlang, etc. that have cores that basically never change and just add quality of life improvements, and so I have never experienced this. C++ seems like such a minefield that C++ developers have little in common with how other C++ developers work, experienced or not.
- missblit 4y agoFWIW as a professional C++ programmer since I graduated university 7 years ago I haven't really had that experience. There's certainly a large learning gap; both for "classic" C++ as well as the popular modern features. But once you get over that I haven't found other peoples C++ any harder to read than other peoples C or JavaScript or Python. No one's reaching to esoteric features like "..." or atomics unless they're some low level library wizard (in which case all their friends are also low level library wizards) or the situation actually calls for it.
- adrianmsmith 4y agoJava was like that for so many years, it was fundamentally unchanged for decades really. And now (for the last 5 years or so) it's changing rapidly, new code just doesn't look like old code ("var" type inference, lambdas rather than inner classes in many cases, multi-line strings with """, new switch statement syntax etc.) I mean I like it so far but it's kind of weird to be honest!
- jcelerier 4y agoC++ people have a large propensity to complain though. We're more than a decade after type inference, one of the largest QoL improvement possible, was introduced and some people still claim it was a bad thing and that all types should be written down in their entirety. Do you imagine this in your language's communities? I had discussions about this with dozens of c++ programmers in real life.
- int_19h 4y ago> Do you imagine this in your language's communities? Absolutely! C# introduced "var" back in 2008, and to this day there are people arguing that you shouldn't use it except when it's outright impossible to spell out the type. From what I hear, it's the same story with "var" in Java 10.
- jesse__ 4y agoI don't like replying to this type of comment, but I'd like to point out that you're replying to someone who likely grew up writing 6502 assembly (or the like). Furthermore, even mediocre engine programmers have an extremely good grasp of memory management et. al. I also don't think they're arguing cxx98 is a good language, especially by today's standards. The argument they're making is that the tact C++ has taken in more modern revisions is actually _worse_ than writing code the shitty 1998 way. At least for axes games care about. You mentioned move semantics, which is a great example. For a lot of game/engine code, move semantics are just adding a pile of complexity for negligible gain. Ie. Why not just use a pointer?
- wiseowise 4y ago> The argument they're making is that the tact C++ has taken in more modern revisions is actually _worse_ than writing code the shitty 1998 way. They didn’t have any argument. Just old man yelling at cloud. > You mentioned move semantics, which is a great example. For a lot of game/engine code, move semantics are just adding a pile of complexity for negligible gain. Ie. Why not just use a pointer? Because it is error prone.
- int_19h 4y agoOnce you're passing pointers around, you have to manually track lifetimes of things they point to.
- _gabe_ 4y ago> This kind of claim is extremely common HN but utterly foreign as someone who actually writes C++ for a living. OP said: >> I've been engineering videogames in C++ for almost 20years working on AAA games It seems like you're implying that every single business domain uses C++ the same way that your business domain does. Instead of insinuating OP is a common HN commenter that doesn't write C++ for a living, which seems to be an incorrect assumption, maybe you should recognize that not every business domain uses the same subset of C++ as you? Your comment just reads as an arrogant opinion hiding behind a false sense of authority. It sounds like you're saying, "anyone that disagrees with my opinion must be some hobbyist programmer that doesn't know what a real programmer that does this for a living actually codes like". As if coding in a language for your job automatically implies that the code will be of a higher quality than hobbyist code. Its gatekeepy and gross imo. I've worked professionally with disgusting C++11 code that was an amalgamation of code from some people that clearly knew what they were doing, and a lot of code that seemed to be from people that had no clue what was really happening. They had no clue because of all the hidden complexities in modern C++ that Herb Stutter is trying to reduce.
- parker_mountain 4y ago> This kind of claim is extremely common HN but utterly foreign as someone who actually writes C++ for a living. This should be a huge klaxon for the C++ community. Whether or not it's true, it's a massive problem for the C++ one way or the other.
- rramadass 4y agoThis comment is classic "not even wrong". >This kind of claim is extremely common HN but utterly foreign as someone who actually writes C++ for a living. The above comment is equally applicable to their comment.
- AussieWog93 4y agoTo be fair, video games are different to a lot of other types of software, in the sense that performance is absolutely critical but (certain types of) bugs can often be excused. One could see why it's more important for a game dev to have a language that forces your mental models to more closely match what the hardware is actually doing, rather than using abstractions that make it less likely that you'll introduce bugs.
- SleepyMyroslav 4y agoi am not the guy you replying but i have my 10+ years in the area. You are voicing something that was true very long time ago. In world where you must be cross play cross platform to cover enough players there is no room for "what the hardware is actually doing". There only few games made by platform holders with exclusivity in mind are still there.
- anonymoushn 4y agoGames that use RAD game tools tend to ship a bunch of platform-specific SIMD code.
- SleepyMyroslav 4y agoyep, middleware authors have more time to write SIMD code because they have less moving targets like platform generations. Nobody needs to read that code anyway ^^
- maccard 4y agoSo do most games using any middleware. Unreal's math, string and core libraries use platform specific instructions, and do so in a c++ friendly way. That's not a justification for writing a bunch of hyper low level dangerous code to run a raycast!
- 01100011 4y agoAgreed. If I want to write maximally performant code I'll write my own abstractions and use C or very little of C++. If I want to write fairly performant code quickly I'll reach for C++ and use more of the toolbox.
- chlorion 4y ago>They don't need a move constructor because they've been already clever enough to solve a prolbem from a different angle. How would you implement something like unique_ptr without move semantics? Can you give an example of angles being used to avoid needing move semantics?
- jesse__ 4y agoExceptional engineers I've come across unilaterally don't use smart/unique/whatever_ptr. A common theme is that they employ allocation strategies that avoid the need for 'micro' memory management in favor of 'macro' management strategies. Allocating large blocks of memory at a time and freeing it all at once is one specific example.
- ladberg 4y agoHaving worked on a few decently large C++ codebases, I can confidently say that this is not how I view things. Shared pointers might be pretty drastically overused by some programmers but have use cases, and I think unique pointers are pretty invaluable. I can't imagine writing a long running, memory conscious, and fast C++ program that uses whatever 'macro' management strategy you envision.
- deleted 4y ago[deleted]
- anonymoushn 4y agoThis is pretty simple actually! At startup, create some object pools, arenas, or bump allocators. Then, never heap allocate anything ever. We also happen to do 0 other steady-state syscalls (not just 0 mmap, munmap, mremap, etc.), so we can just run the program under valgrind and any time valgrind prints something is a bug. We didn't use C++ but some other software I've heard uses a similar approach is written in C++.
- jart 4y agoAs someone who got scolded by Jeff Dean once for using smart pointers, I can attest to this.
- jupp0r 4y agoC is overcomplicated and all really hardcore engineers that I've met either write assembler or carve binary machine code into stone blocks with their bare teeth at moonlight.
- rramadass 4y agoWell put! Much of the C++ code out there is still C++98 and a lot of the "so called problems" had already been solved by using established code patterns (not GoF). "Modern C++" has added a lot of complexity but not for much benefit; its fanboys always use hand-wavy phrases like "much nicer", "makes programming simple"(!) etc. which mean nothing. After the introduction of STL and explosion in the usage of "Generic Programming" the only thing the language needed was Concurrency support for Synchronous/Asynchronous programming. Instead the ISO committee went off the rails into "modernizing" the language to try to make it like Python/whatever. The result is that experienced C++ developers are very cautious about adopting "Modern C++" while the larger "know little/nothing" crowd are raucously running around making all sorts of unwarranted claims. IMO, today the greatest enemy of the language is the ISO committee itself.
- wiseowise 4y agoYou say a lot of words, but have substance. Which “so called problems”? Which “established code patterns?”. Why “it means nothing” and to whom? I can continue.
- rramadass 4y agoThis is the old trope of asking for proof from one side in a forum where things are discussed freely. I could turn it around and ask you to justify all the new "features" added to say C++11..20. I am here for the rest of time. But to give a few concrete examples; >Which “so called problems”? Apparently "variants" were introduced to solve problems with POD "unions". Mere complexity for not much benefit. Nobody i have worked with ever said "unions" were difficult to use. >Which “established code patterns?” RAII as a solution to People harping about memory problems. I have written entire protocol message libraries just using RAII to avoid memory leaks. >Why “it means nothing” and to whom? When "Modern C++" proponents say everything should be written with the new features using hand-wavy phrases, "it means nothing" to experienced programmers. If we find a feature useful to model a concept and/or express something we will use it; but always weighed against how complex it is to read and maintain. A good example is template meta-programming taken too far. The key reason C++ took off was because it added minimal "Zero-Overhead abstraction" constructs over the baseline "low-level and simple" C core. Suddenly programmers could have their cake and eat it too. The evolution of C++ should have continued in the same spirit but instead in a misguided effort to compete with later and differently designed languages a lot of complexity has been added for not much apparent benefit.
- jandrewrogers 4y agoIn database engines, where C++ is pervasively used, modern C++ is a vast improvement over legacy C++. It is much simpler and safer. Writing a current C++20 database kernel in the equivalent legacy C++ would require several times more lines of code, and that code would be much more difficult to maintain aside from the much greater volume. A database engine implementation makes very good use of modern C++ features, the idiomatic legacy C++ equivalents were often very ugly and very brittle. I've done both. I have never worked on games -- maybe that domain has simpler internals -- but there are important categories of C++ software outside of games that unambiguously benefit immensely from the modern C++ features. In databases it is common to ride as close to the bleeding edge of modern C++ as is feasible because the utility of the new features is so high.
- gigel82 4y agoI've been programming professionally in C++ for 15 years and can say I wholeheartedly disagree. I'm looking forward to whenever our engineering team adopts a newer compiler version in our legacy codebase (sadly we're stuck at C++17 for now). Whenever I move from the old-style C++98 code units to newer modern C++ ones I breath a sigh of relief. It's beautiful, safe and modern; it reads like poetry. If I get a code review where someone manually calls new/delete I will fail that code review. That said, I agree this proposed "new syntax" is ugly and unreadable and unnecessary.
- arinlen 4y ago> Modern C++ it's overcomplicated and from what I can see all the best software engineers I met in my careen write very simple C++98 code, maybe a bit of C++11 but that's it. I'm sorry but this assertion does not pass the smell test. Sticking with C++11 means you do not have std::make_unique, and any claim that these "best software engineers" not only fail to use smart pointers but also refuse to even consider instantiating a std::unique_ptr in a safe, standard way and for no reason at all is something that lacks any credibility. > Modern C++ is for experienced C++ developers It really isn't. "Modern" C++ is just the same old C++ with useful features that improve the developer experience (see aggregate initialization, for starters,nested namespace definitions, utf8 character literals, structured binding, etc) and don't require developers to resort to in-house trickery passed around through tribal knowledge to implement basic features (move semantics, constexpr, etc). > It's just disappointing... Speak for yourself. It's fantastic that people continue to improve the language and make everyone's life easier, instead of being stuck in the C++98 mud. Each and every single major standard release since C++98 brought huge productivity and safety improvements that everyone stands to benefit. Even standardizing stuff from Boost and the like is a major step forward. It's totally fine that you personally prefer to not benefit from any of the improvements that sprung in the past two decades, but don't presume for a minute that you represent anyone beyond yourself when making Luddite-like claims.
- badsectoracula 4y ago> Sticking with C++11 means you do not have std::make_unique, and any claim that these "best software engineers" not only fail to use smart pointers Pretty much every non-trivial C++ engine i've seen has its own equivalents for memory management. Even a game engine development book i bought in ~2001 (meaning it was written before then) had a chapter dedicated to implementing smart pointers.
- bipson 4y agoWhich doesn't mean that they are any better than the provided standard implementations. They are there because it makes sense to have them. Now you don't have build and maintain your own ship.
- germandiago 4y agoThe problem with videogames niche seems to be that the debugability of code suffered, as well as the speed, in debug mode. There are lately some improvements to that, like making move/forward an "intrinsic" from the point of view of the debugger. Also the SIMD interactions seemed to be a problem in certain loop vectorization. As for "you are clever bc you do not use move constructors"... I can be clever and use assembly instead of C. But I am not sure it would be the right choice in all scenarios. If you have a tool and can take advantage of it, just make use of it.
- maccard 4y agoIve been working on AAA games for a decade writing c++, and I couldn't disagree more. An enormous amount of "smart" old school c++ is at best equivalent to a well written modern equivalent, and at worst more dangerous, error prone and slower. Anything that uses references for writable out parameters combined with a bool return value (or no return value) for success is a great example. On my last project, I rewrote a bunch of fundamental Unreal Engine path handling methods, replacing the old school bool GetXXX(TCHAR* In, TCHAR* Out); with FStringView GetXXX(const FString& In); In the process of doing so I found multiple engine and game bugs that in the best case were logic bugs and in the worst case were memory safety issues. I also left the original function call in place and made it wrap the new version with no perf overhead for the callsites I didn't change, and a 30% increase for the cases that I did fix. Almost all of that is because I stopped requiring null checks, I was able to lean on RVO and move semantics, and I was able to avoid unnecessary initialisations in many places in the code. Most of the sites I replaced were calling FString ThingStr; TCHAR* Thing =<...> if (GetXXX(FooStr.c_str(), Thing)) ThingStr = FString(Thing); And most were replaced with FStringView Thing = GetXXX(Foo); > write very simple C++98 code, maybe a bit of C++11 but that's it. They keep it simple. Assuming of course there's already a smart pointer library that you're using, modern c++ allows for simpler, more correct and faster code in many many places. Some examples are auto: for( map<string, int>::iterator it = map.begin(); it != map.end(); ++it) becomes for (auto& it: map) nullptr is now a thing over NULL, move semantics make it feasible to write logical code without needing to jump between logic and type manipulation for basic operations, static assertions exist, enum class, attributes (nodiscard, noreturn, deprecated),constexpr and all the evolutions that came with it, structured bindings, concepts, if/for initializes... All of the above are just off the top of my head features that I interact with daily, even if I don't write them daily, all of which make my code and project safer faster and easier to understand. > This new C++ syntax is just a gimmick that we don't need. I disagree. It has many useful properties. It gave us the spaceship operator which massively simplifies the code needed to write correct objects. A single well written spaceship operator can mean numerous algorithms just work on containers of your type, rather than custom filter/search operations. The syntax of left to right definitions for functions _seems- superfluous but it drastically reduces the amount of work needed to be done by the compiler which should translate into real world compilation speedups. The import/include swaps could allow for new code to interact with well behaved old code in a safer manner. As someone else said on this thread, it's not always about one feature in isolation, it's about combining multiple features and the result being worthwhile.
- spacechild1 4y agoThat's an interesting perspective. I started writing C++ after C++11 came out and personally I can't even imagine writing C++ without auto, move semantics, lambdas, variadic templates, std::unique_ptr, std::atomic, etc.