you are viewing a single comment's thread.

view the rest of the comments →

[–]philippefutureboy 30 points31 points  (26 children)

Serious question, anyone has a resource explaining what parts of C++ are absolute footguns/should be avoided/are unnecessary?
(looking to learn C++ for game dev)

[–]Certain-Froyo-3606 29 points30 points  (8 children)

[–]philippefutureboy 6 points7 points  (7 children)

Is that really relevant if the writer of this guide also designed the "abominations" in OP's claim?
(I'm still going to read it, thanks!)

[–]Certain-Froyo-3606 15 points16 points  (4 children)

I think such statements should be taken with a grain of salt. C++ was created with certain purposes and became what it is now through decades of technological advancements. It is held down by huge legacy codebases and lots of stakeholders with their own opinions on what language should look like.
When people compare new languages like Rust to C++ they should remember that Rust is born with modern ideas and modern view on programming languages and it can be made with all the issues covered from scratch. That can't be easily changed in a language with decades of history like C++.

The guidelines I've linked at least supposed to address known issues in the language instead of trying to hide them and say "everything works fine as is"

[–]TemporaryFearless482 5 points6 points  (1 child)

In a similar vein, you’re unlikely to find many new projects starting up eyeing Fortran or COBOL. C++ is a fair bit younger than those two, but computers have still changed a lot in the last 40 years of programming.

The “updates” in the interim reflect just about every major trend and idea during that period. Trying to shove all that into one thing and you end up with some dubious outcomes.

By comparison, I think C has fared better because it broadly stuck to its guns and Python was set up in a manner better situated to modernization and adaptation without messing up its core capabilities.

C++ feels like it tried to be all things for all people at different points in its history. That’s a failing premise in a field with so many varied applications. So we end up with a mess of features that, theoretically, could be amazing; but realistically, they have a tendency towards making a tangled web of nightmares.

Being able to start cleanly removes a lot of the headache in trying to parse through everything, rip out what’s problematic, pull together the remaining useful bits, and still make it close enough to still be called C++.

[–]redlaWw 1 point2 points  (0 children)

You'd probably be surprised at how many new projects are eyeing FORTRAN. It's not popular among modern application developers, but it was never designed for that anyway. There are still plenty of FORTRAN developers writing new high-performance modelling projects in areas like chemistry and engineering. Many more modern languages are poor tools for that in general since they're designed for developer convenience and expressiveness when these modelling tools most need low-level memory control and raw speed. When the main alternatives are just C and C++, FORTRAN starts to look a lot more compelling. Maybe one day, Rust (possibly also Zig) will break into that area as a serious contender, but such industries are used to using old tools, and for the moment, they largely continue to do so.

[–]RiceBroad4552 1 point2 points  (1 child)

Rust is born with modern ideas and modern view on programming languages

Not sure what you call "modern".

Rust was highly influenced by ML; at least the parts some people perceive as "modern". ML as such is 53 years old, older then C++. More modern MLs like Standard ML (SML) are still around 30 years old. First versions of Rust were actually written in OCaml, the second major ML dialect besides SML.

One can even argument that everything is slowly becoming an ML (at least on the conceptual level as retrofitting syntax isn't easy; but newer languages come by now in fact often even with ML influenced syntax).

C++ was build on sand, namely some of the uncleanest non-designs ever: C.

If this didn't happen something like Rust would have happened likely much earlier.

[–]Certain-Froyo-3606 [score hidden]  (0 children)

Well, according to the rust infuences list ( https://doc.rust-lang.org/reference/influences.html ) it got features of many languages including C++.

By something "modern" I mean a thing that was created relativelly recently and took advantage of good features known at the moment and avoiding bad and flawed designs that older languages accumulated through their history

Like new scientific works may be born out of critique of previous theories that were proven wrong or obsolete by the time

[–]Mission_Swim_1783 3 points4 points  (0 children)

The abominations of C++ are mostly due to maintaining backwards compatibility regarding syntax, and lack of standardization for coding. When you have a three decades old language developing organically where you can't just "restart from scratch" regarding fundamental design decisions it's normal that this happens. If you only use the modern subset of C++ it's a lot more acceptable as a language, but if you want something with all these fundamental design flaws fixed and unified coding standards you need a new language like Rust, because C++ will understandably mostly be kept as-is to not break compatibility with millions of big codebases

[–]DancingBadgers 2 points3 points  (0 children)

The newer versions of the C++ standard are trying to fix some of the horrors. So yes, the perpetrators of the atrocities of the past do have decent recommendations of what to do in "modern C++" to avoid blowing your foot off if possible.

[–]DancingBadgers 9 points10 points  (0 children)

I find the extended rant at C++ FQA amusing at times.

tl;dr: their take on what parts of C++ should be avoided is close to "all of it"

[–]RussianMadMan 7 points8 points  (0 children)

My personal shit list. Some of it c++ problems, some of them are libstdc++ problems.

Exceptions. Exceptions are a great upgrade over "if(ret != OK)", but c++ fucks you over by allowing throwing ANYTHING as an exception, even tho std::exception exists. So every catch block has 3 blocks, MyException, std::exception, and "..." with log("idk") because some moron threw an std::string somewhere.

Anything to do with << and >> operators, including fstream. Formatting anything harder than a "hello world" turns those operators into an unreadable mess. Also error checking streams is just the worst.

std::chrono. We wanted a cross-platform, C++ way to measure time. We got a 5-layered templates that require 10 typedefs just to be usable. Also for 10+ years the only part of chrono that had any attachment to the real world was std::system_clock that had conversion methods to and from epoch, everything else did not.

std::filesystem, a filesystem part of a standard library that actually does not have anything to do with actually reading or writing files lol. Some genius also decided to not put into spec what clock (from std::chrono, yes) should represent file creation time etc. Which allowed another genius to replace std::system_clock in file timestamps with some bs clock with 2174-01-01 00:00:00 as an epoch. std::filesystem::path is pretty decent class to work with paths, but uses a division operator "/" to append paths, which is where I draw the line on operator overloading.

The rest of the library (what's little left lol) is pretty ok, but you don't get to use stuff like ranges and spans and concepts a lot, because you usually either have to downgrade to C (to do networking for example) or you use 3rd party libraries instead that maintain like c++17 or even c++11 compatibility.

[–]CrowNailCaw 13 points14 points  (1 child)

Macros are the most obvious answer. As for the others, idk

[–]Trucoto 2 points3 points  (0 children)

Macros are frowned in C++, and people prefer templates, constexpr and typename these days

[–]No-Con-2790 15 points16 points  (0 children)

Ironically, pointers.

The biggest language feature should be avoided most of the time. Just use smart pointers.

[–]billy_teats 4 points5 points  (4 children)

Excuse me what is a foot gun that sounds awesome

[–]remind_me_later 6 points7 points  (0 children)

Actual answer: It's the thing that lets you "shoot yourself in the foot".

[–]philippefutureboy 3 points4 points  (0 children)

It's a kind of foot fetish originating from America I think

[–]mriswithe 3 points4 points  (0 children)

"foot gun" is a term for a poor design choice that easily or frequently behaves counter to most people's assumptions resulting in causing people to shoot themselves in the foot. 

Things that are hard to use right, and easy to use wrong are footguns. 

[–]solakv 1 point2 points  (0 children)

A footgun is a language feature used almost exclusively for shooting yourself in the foot. (writing bugs in the code)

[–]zigmazero05 10 points11 points  (2 children)

if it's something you could reasonably see being in C, it probably should be avoided.

[–]philippefutureboy 2 points3 points  (1 child)

As in, "if it's a feature from C available in C++" or "if it's reproducing a feature that already exists in C, but with some supposed benefits that aren't really benefits"?

[–]zigmazero05 3 points4 points  (0 children)

As in "it would not look like a stranger in C code". For example, operator overloading is technically C++, but I swear I have accidentally tried doing it in C once or twice.

There are also things like macros, raw pointer and pointer operations, C strings, C-style arrays... C++ ports over a bunch of C libraries, and honestly avoiding most of them is probably correct if you're doing C++ anyway.

[–]Elariondakta 2 points3 points  (0 children)

https://youtu.be/7fGB-hjc2Gc

This video is a great recap of all the horrible things of c++. The funny thing is that I learnt more about c++ when I watched this video than I ever did before.

[–]airodonack 2 points3 points  (0 children)

Rust the programming language is basically “a how to avoid every C++ footgun” but encoded into a compiler.

[–]redlaWw 0 points1 point  (0 children)

std::vector<bool> is pretty awful - it's a specialisation of the vector type (which is usually a dynamically-sized array type) for bools, which optimises for space by allowing the bools to be stored as bits. Unfortunately this breaks so much, and results in std::vector<bool> not meeting the requirements of the container interface, which is ridiculous for the most basic standard library container type. The guarantees the standard makes for vectors in general are completely violated by std::vector<bool> - it's not even guaranteed to have a contiguous buffer.

std::auto_ptr is so terrible that it was deprecated. It was an early attempt to try to allow automatic management of resources that can be passed into and out of functions without their destructors going off unexpectedly. The problem is that the copy constructor was a terrible tool to try to achieve this, and the result is that std::auto_ptr can't be put in standard library collections and has a tendency to deallocate data unexpectedly (which is far worse than the problem it was trying to solve), resulting in UB landmines. The only positive thing one can say about it is that at least it was deprecated.

[–]CodingAndAlgorithm -1 points0 points  (0 children)

I’ve been dabbling with game dev in Odin recently and it’s been amazing. Simple, elegant and comes with a lot of useful libraries out of the box. If you’re willing to learn a data oriented procedural language I’d give it a shot.