If I was starting a new work project with a lot of junior team members, or if I was doing a web project, or a very simple script, fine I’ll use a different language. There can definitely be good reasons not to use C++. But I’m at the point in my expertise that I will default to C++ otherwise. I’m most productive where I am most familiar.
With all due respect to your expertise, the whole idea of a footgun is that it tends to go off accidentally. The more footguns a language contains, the more likely you are of accidentally firing one.
This is “I use the language I always use because I always use it”, and not actually a praise or C++ specifically.
In my 21 years coding professionally, I will settle on C++ or Ruby for most problems depending on context. Ruby for quick, dirty, and "now!", while I use C++ for Long lasting, performance, strongly typed, and compatible things. Those aren't perfect categories and there are reasons to pick other tools, but Choosing C++ after a long career does mean something more than "I am comfortable with this".
Does it?
If you are fortunate enough for your domain to have good IO libraries then there is a chance you can do everything the "Modern" way avoid a lot of the headache and avoid most of the footguns entirely. That maturity and omni-pattern availability is potent, but all that power does come with the possibility of mistakes or surprises.
Compare to newer languages where we don't know what might break or might need to do something the language omits as part of its paradigm. I have done a ton of Ruby projects and about half the time we need more performance so I need to bust out C to rewrite a hotspot in a performance sensitive way. Or sometimes you just really want a loop not a functional stream enumerator like is the default in Ruby. For a new language, Theo tried the 1 billion row challenge in Gleam and the underlying file IO was so slow the language implementers had to step in.
This is an engineering and a business choice. There are reasons to avoid C++ and footguns, like any risk, are among them. These aren't risks without mitigation, but that mitigation has a cost. Just like newer languages have reasons not to use them. A team needs to pick the tools with risks and other cons they can handle and the pros that help them solve their problem.
The problem is that your definition of risk may not be the same as others', and so there isn't always agreement on what is ok and not ok to do. And regardless, humans are notoriously bad at risk assessment.
> This is really well explored space in C++. Just using value semantics, shared_ptr, and RAII instead of naked news and reckless mallocs would improve several "old" codebase I have worked in. Maybe people shouldn't be reaching for const_cast so often, and similar.
Right, and all that is exactly the point: all of that stuff is in wide use out there, and I suspect not just in "old" code bases. So there's still not consensus on what's safe to use and what's too risky.
And regardless, I have enough to think about when I'm building something. Remembering the rules of what language features and APIs I should and shouldn't use is added noise that I don't want. Having to make quick risk assessments about particular constructs is not something I want to be doing. I'd rather just write in a safer language, and the compiler will error out if I do something that would otherwise be too risky. And as a bonus, other people are making those risk assessments up-front for me, people in a much better position than I am to do so in the first place, people who understand the consequences and trade offs better than I do.
I really like this value proposition: "if the compiler successfully compiles the code, there will be no buffer overruns or use-after-free bugs in it" (certainly there's the possibility of compiler bugs, but that's the only vector for failures here). For C++, at best, we can only say, "if you use only a particular subset of the language and standard library that the compiler will not define or enforce for you (find a third party definition or define it yourself, and then be very very careful when coding that you adhere to it, without anyone or anything checking your work), then you probably won't have any buffer overruns or use-after-free bugs." To me, that's almost worse than useless; even if I find a C++-subset definition that I think is reasonable, I'm still not really protected, because I still have to perfectly adhere to it. And even if I do, I'm still at the mercy of that subset definition being "correct".
Is a footgun a gun that only aims at feet? Because that seems like a dumb thing to invent in the first place. Or is it a gun that happens a to be aiming at feet? That seems like something that could only exist by user error.
I think “enough rope to hang yourself” is a more accurate description of almost every programming languages, since rope is at least intended to be useful (although it is a bit more morbid of an analogy).
This is a footgun - the way to avoid the holster firing is to simply not wear sunglasses, or keep something in your left pocket, and then it would never fire. But the problem is that both of those things are extremely common (for good reason). It’s a poorly thought out feature because it has severe consequences (potentially shooting your foot) for extremely common situations (wearing sunglasses and using your left pocket).
I think you're being a bit too literal. It's not an analogy at all, and this has nothing to do with firearms best practices. If we were to define a footgun as "a gun that is only capable of shooting you in the foot" (or perhaps more broadly usefully, "a gun that in theory can be useful, but it is nearly impossibly difficult to make it do anything other than shoot you in the foot"), then the entire point of using the term is to describe something that has no useful, logical purpose, and is unsafe to use, even as designed.
Being "given enough rope to hang yourself" is indeed another good idiom to use for things like this, but the implication is different, I think: when you're given enough rope to hang yourself, the outcome is still very much in your hands. You can intentionally or unintentionally use that rope to hang yourself, or you can be reasonably expected to use that rope in another way that would turn out to be safe or useful.
"Footgun", by contrast, is used to describe something that has no (or negligible) safe uses. Maybe the original intent behind the design of what's being described that way was to have safe uses, but ultimately those safe uses never really panned out, or were so dwarfed by the unsafe uses that the safe use isn't worth the thing existing in the first place. But, unfortunately, there are some people -- maybe only 0.01% of people -- who are able use it safely, and critically depend on that safe use, so we can't completely destroy all these footguns and save everyone else from the error of their ways. And unfortunately most everyone else sees these 0.01% of uses, and believes they are so useful, so efficient, so brilliant, they want to try it too... but in their hubris they end up shooting themselves in the foot, like most others before them.
> 1972 - Dennis Ritchie invents a powerful gun that shoots both forward and backward simultaneously. Not satisfied with the number of deaths and permanent maimings from that invention he invents C and Unix.
Some of us learn to lean to the side right before pulling the trigger...
http://james-iry.blogspot.com/2009/05/brief-incomplete-and-m...
It is any trap in something technical that is likely to cause problems from perceived normal use.
Compare to related terms: "Pit of failure", "Turing tarpit", and "Pit of success".