Why I haven't given up on C++
josephanders0n.github.io
josephanders0n.github.io
IMO it's a language that well suits pragmatic programmers who are willing to cherry-pick the most convenient and productive features for their projects and leave the rest alone.
It's a terrible language for those of us who compulsively try to be clever and use every little nook and cranny of the language they're using. They get lost out in the dark scary corridors and spiderwebs, and then say "C++ sucks" instead of "what the hell, don't go out there unless you really NEED variadic templates today."
Edit: And it's easy to get yourself in really weird pickles if you don't know what not to do, (static initialization order, I'm looking at you!) I've found my WTF-per-minute rate has dropped dramatically over the years as my coding style has improved.
Use good language features, eschew the bad ones (paraphrased).
After reading this, some opinions across a few languages made more sense. For example, Crockford advocates subsetting, hence JS The Good Parts. There are also more times than I can count where choosing a subset of C++ from its stupendously large array of features.
When you think about it, it's possible to write esoteric, hard to read code in many languages, even ones designed to improve programmer productivity. If a language offers you capabilities that can blow readability out of the window, you'll see it happen. The more capabilities for such and the larger the number of programmers using the language, I'm sure you'll see a larger number of cases where code is indecipherable.
From experience, to finish, I've seen a lot of very straight-forward C++ code that shines with readability compared with some Python code I've come across.
It kinda does. It's like Perl: between the historical precedent, the stuff that's available on the interwebs, the affordances of the language and the easiest/shortest way to solve a given problem, it's way harder to code portably, maintainably and effectively than not, and you need to expend serious efforts trying to keep up. Which most people aren't going to do.
It's the old quip that "within C++, there is a much smaller and cleaner language struggling to get out". If you have the knowledge and the discipline you can use that smaller and cleaner language, but I don't think you can argue it's easier to use that smaller and cleaner language than to use C++ in general.
The trick, in my opinion, to C++ was what you were not doing. Coding in such a rich language means making a lot of decisions up front about limiting complexity. That turns out to be a good thing.
The reason it's not my favorite anymore? Because the language designers seem hell-bent on continuing to make it more and more feature-ful. Over time, it's creating a huge, diverse codebase, all with the title "C++ code" on it, but all vastly different in nature and scope. That ain't a good thing.
STL is a good example. On its own, STL is a good thing. Greatly needed in the language. But now that its implemented, its basically its own system. You could solve world hunger with STL (I am being factitious to make a point) Remember the criticism Microsoft always had, that they couldn't build anything that did just a few things? Everything had to be able to do everything? C++ has that, only worse.
I like the language. I really do. I don't know if I've given up on it -- unless I wanted to tweak the hell out of something or was writing lower-level code the answer is probably "yes" -- but it seems to be heading in a direction that is not good for the maintenance programming community. It's great for really smart people who love complex things, but no so much for the poor schmuck coming in 10 or 15 years later. It's become a monster.
Having worked with it a large amount at this point it seems to me to be mostly very well designed and focused on fundamentals of the parts of a program that are both common and non trivial.
Some things are messy (like hashing) some things are missing (like serialization) and some things would be incredible to have (like thread local heap allocation, lock free concurrent data structures, some sort of dynamic stack allocation, the functionality of something like capnproto, shared memory and memory mapping...), but in general it seems like it covers the fundamentals well.
Do you mean the Boost developers? :)
As someone who's currently rewriting a massive Java project in C++ so we can port it to other platforms, this made me laugh.
It reminds me of that physicist joke about spherical cows. "Assume a working JVM..."
Each time, more than 90% of the migration workload was on the C++ code.
C++ only recently is starting to go there.
The main issue is that Java's portability has hard limits. C++'s may require work, but it is at least (in theory) almost always possible.
Java was an welcoming bless when it appeared in terms of code portability. Writing portable C++ code in the days of pre-ANSI C++98 was a mess.
"Huh. I'm pretty sure Rust would have picked me up on that bug."
Here's an example. I accidentally wrote this:
while (getLine(pc, buffer, sizeof(buffer) > 0))
Which compiles fine. Stricter languages could detect this bug.The second one could only arise with unsafe pointers in Rust, as safe code uses slices, combining the base pointer and the element count in a single value.
OTOH the point here is to pass a preallocated but "uninitialised" buffer to the callee, which Rust wouldn't allow with slices, unless you created a slice from a raw allocation (I don't know if that's defined behaviour, though I guess you could do that safely by passing in a Write rather than the slice itself, but then you're Write-ing to a slice which has… interesting behaviour)
#include <stdio.h>
static char buffer[80];
static char *bufferp=buffer;
int main(int argc, char *argv[] )
{
char localbuffer[80];
char *localbufferp=localbuffer;
printf("buffer: %ld\n",sizeof buffer);
printf("bufferp: %ld\n",sizeof bufferp);
printf("localbuffer: %ld\n",sizeof localbuffer);
printf("localbufferp: %ld\n",sizeof localbufferp);
}
Output: marcel@sarek[tmp]./a.out
buffer: 80
bufferp: 8
localbuffer: 80
localbufferp: 8
As you can see, it depends entirely on whether you give sizeof the array or the pointer.Of course warnings work until you have source from something external that throws lots of warnings that you can't reliably turn off (possibly due to completely broken and ignored warning bugs in ICC for example).
One anecedote is: "I know I'll use one of the Curl++ wrappers instead of using the normal interface, because C" ... "But this wrapper throws exceptions in the destructor, that is bad and leads to 'interesting' debugging sessions" ... "but C!".
And other numerous of other small gripes... I'm familiar with some of the dusty corners of C++ and I have to constantly educate people about them.
In a way I have plateaued with C++, almost too comfortable with it. I need to do something else.
Sure, most of this stuff is correct, like the header madness, but still C++11 especially is pretty nice these days. There just isn't any other way to do cross-platform, performant code, while having the compatibility with all the C/C++ libraries out there.
I feel C++11 could use some kind of new approach, like "Lean C++11" which drops all the legacy crap that is holding back adaption for new developers, who now have to go through maybe 15-20 years of legacy coding styles in order to find the modern way of doing things.
But this would break backwards compatibility, so maybe better focus on Rust or something else that is set to do things correctly.
I still like C++, although it is more difficult to write in. Add in a scripting language like Lua to C++ and you have a very performant and nice stack of scriptability and close-to-the-hardware stack that feels super powerful.
That's me, about seven years ago. Then I tried Qt Creator. Now I'm an evangelist. It just works. It parses all your code in seconds and you get autocomplete and syntax coloring that's very close to perfect. The interface is as clean as it gets. And yes, you can use it without ever touching Qt (the framework) at all.
The only thing is, try to avoid versions > 3.2.2 since they are a bit buggy.
Edit: fixed typo.
Its complexity is inefficient and this gives the sensation of power and accomplishment, when all we have done is waste energy on translating abstract thought into a fragile foam of symbols. Then finally there is a sad degree of orthogonality between the meaning and structure of said foam and our original thought. But it sure feels like we did something. We slaid that dragon good eh!
>C++ IDEs suck. Big time.
I find Xcode quite a pleasure to use. The autocompletion, debugging, the quick moving around the interface, splitting files side-by-side.. I haven't used other IDEs besides emacs, but nothing about Xcode is getting in my way.
>It’s an unmanageable language.
Compared to a dynamic language or a weakly-typed language (I'm looking at you C, and a few others), I'd say the strong typing of C++ alone helps in code manageability. And, unlike Swift or Clojure or other languages, I find putting an API in a header file and an implementation in a translation unit really helps me reduce time later on. It's an automatic API summary without needing to review your implementation. When I move on from one part of a program to another, I don't want to study my source code just to remember what the access is. Just show me the header. I miss header files in other languages.
>It’s a counterproductive language.
and
>STL sucks.
The tools in the STL are serious time-savers. Sure you can choose not use them or implement your own, but in either scenario, you will likely spend a lot more time writing code than working on your actual problem or idea. In that regard, I'd say C++ and its standard library are very productive. And all the new multithreading and async primitives in C++11/14 take this productivity to a new level.
>namespace stupidity
Without namespaces, you have to work harder to name your stuff and to debug name clashes. Every good language that I've worked with uses namespaces. I consider them a requirement for any language that will handle a large project.
>The language sucks. It sucks because it’s so complicated.
C++ is probably the most complicated language I will ever use. I'm not sure why that makes it suck, though. Unlike many other languages, where it is wise and expected that you can keep the whole language in your head and understand entirely how it works, C++ is a different thing altogether. Nobody on this planet probably understands 100% of C++ -- including its creator, who has said that he gets maybe 80% there. In C++ you can use a small and ordinary part of the language and choose to go to the complicated stuff only if you really want to, but rarely do you need to. Yes, complex metaprogramming is mind-bending in what you can do -- and also, you cannot do a lot of it any other language. But you don't have to do any of that, and most people probably shouldn't, until they want to have some fun and really see how deep C++ can go. And a lot of the most complicated stuff that was important to understand in the past is no longer required reading for new programmers to the language, since the latest standards handle many things for you automatically. I.e. just writing "new" or "delete" and deciding when and how to do so are no longer required and actually discouraged thanks to smart pointers.
`make doc` (maybe as part of your build process even), then view the autogenerated API documentation. This is at least a feature or extension of most languages. C++ even has a number of documentation suites (e.g. Doxygen, IIRC).
Furthermore, if you're using a "good" IDE, I would expect it to be able to provide you the same basic information you get from header files (i.e. method signature & names). It could at the very least have a "collapse function implementations" hotkey to allow you to view a source file as if it were essentially a header file.
I don't know, the fact that it's somewhat trivial to actually generate a .h file given a .c or .cpp file (look up LZZ - Lazy C++; it's not maintained, but it did exactly this) makes them seem pretty much useless to me.
To be honest, this is a corporate sales pitch. It's trying to justify the injustifiable
It doesn't need to be full of "features" that most people don't use. Granted, some of them are needed regardless
C++11 and 14 have simplified some parts, which is good. Still, a lot of other languages do more with less complexity
Some things that are painful
- String formatting in STL is a joke
- "Smart pointers" are still an add-on and clunky to use
- No reflection. Manual setup of getters/setters/copy constructors
Flexibility should not imply in being "hard to use"
Without boost::format and boost::algorithm, std::string is a major pain in the ass to work with. Even including those two, there's still the distinct lack of unicode-awareness (and no, wstring doesn't help, and neither does "let's pretend it's all utf8 underneath".) And then there is the institutional problem that nobody agrees on whether, and if so how, to use std::string in their libraries' API's.
But on the bright side, string handling in C++ is not as painful today as it was in 2005, things do get better.