A Common MisconC++tion
This isn’t for those in the know, really. If you are a C++ developer, chances are you already know what I’m going to say. However, if you’re fresh and hear the mention of C/C++, you might want to look at this.
So let’s start: C != C++.
Okay, but why?
It’s something that my university hinted at, but failed to properly convey. I learned this myself and I actually grew to like both languages a whole lot more the moment I realised their differences.
We all know that C++ is object-oriented, with some reservation, and quite compatibile with C. But C is a structured language and they have diverged over time.
Modern C++ is a wildly different beast from C++98, the standard most people think of when they say “C++”. I saw that in class and lectures; what was sold to us as C++ was actually a hodgepodge of C with token C++. While modern C++ also has its problems, I’ll highlight the misconceptions I’ve ran into while fiddling about.
Okay, I’ll just share what I learned about the differences while fiddling about with Windows bitmaps in C and C++. This is pretty much the list of what my uni lecturers and slash or tutors neglected to tell me about.
First: I Am So Getting Death Threats, But Use iostream.
Why? Google uses printf, scanf and fscanf and so on. You can use these, of course, but that doesn’t mean you should. I dug into the Big G’s style guides and they explained it nicely: the amount of code they already have relying on the C-style input is just too hard to overlook. They did it in the name of consistency.
But if you’re not Google, I’m going to say it: use the C++ way. The C++ standard output via iostream has its peculiarities, but it’s in the std namespace. Indeed, this is about consistency: I found out that embracing C++, rather than clinging to C bits in it, really smooths things out. This is precisely what comes as a caveat to everything else in this post. Mixing C and C++ results in a mess.
Don’t get me wrong — I’m guilty of using <stdio.h> myself. And there’s a lot of heated arguments about performance — but iostream is actually worth it.
Second: I cast MagicMissille at void!
Use C++ style casts. I’ve also used things like (int)a_char in my days. You should remember that C++ is generally more fickle about its types. While it’s a little tempting to use C-style casts. Consider dynamic_cast and reinterpret_cast — I actually appreciated the clarity that came with it when I was fiddling about with binary files.
The more verbose casting managed to get some mental overhead away — I specified how I wanted things cast instead of casting and hoping for the best. It was more helpful than I anticipated.
Third: malloc… wait, I can do new int[count]!
While dynamic-length arrays in C require you to do some black magic involving a void pointer-returning malloc, you can just use a construct from C# or Java. Turns out, C++11 actually lets you declare dynamic arrays like newer languages instead of flaky malloc casts.
Fourth: The Standard Library is Neat
Okay, it tends to explode with weird compile time messages, but things like vector or map really help. And they perform well. And uni instructors somehow neglect to mention them most of the time in favour of reinventing the wheel… in idiomatic C. No plus plus there.
Fifth: It’s Not NULL, silly
Back in the day, the way to say there’s no reference was a zero. Zero served as the null pointer, but that easily runs into a bunch of issues. Java and such created null to sort that out.
Enter nullptr. It’s a weird name, but it brings the advantages of a proper null value to C++. I wouldn’t have said it was great if it didn’t actually help me in a few cases.
Sixth: Smart pointers
Yeah. These guys. You get std::unique_ptr and std::shared_ptr. They’re fast and they might save you a memory leak — you don’t have to delete every single thing manually if you use them right.
Just use objects and classes. Remember that :: is for namespacing and statics, -> for dereferencing and the full stop is for non-pointer objects and you’re golden. With the nullptr and smart pointers, C++ OOP isn’t all that scary anymore. C++ objects felt less flaky than C structs in use. Of course they’re not the same thing, but their syntax didn’t bite me in the rear end as much.
Eighth: It’s Supposed To Be Constant
C lets you do this:
const int a = 2;
int *b = &a;
b* = 4;
C++ doesn’t. It protects your constants and doesn’t let you write straight to an address of a constant. Generally, C++ is also more type safe. It’s still less whingy about it than, say, C#, but a lot of valid C can actually blow up if it does risky things like this and is compiled as C++.
Is that it?
Well, not really, that’s just the things I found during a small personal project. Most importantly — all these things are things my lecturers were unaware of or uncomfortable with for some reason or the other. And they actually helped me make things work faster and more reliably. There’s a whole lot more to C++. Just these eight little things resulted in two things.
The code looked noticably different from the C code I threw together, and that C code was actually quite OOP-ey (don’t ask how, it was hellish in so many ways but it was actually more fun than I expected).
And it ran faster. Of course, C would’ve gone as fast if I rewrote it in a slightly more sane way instead of exploring C’s quirks, I was also exploring C++’s quirks, so it makes sense in a way.
The bottom line is, a lot of people who mention C++ actually speak of a creature best described as C / C++ which is a messy mix of the two. I’d honestly recommend checking both languages out and actually looking at reference materials, as it quickly shows a lot of interesting differences — and it can really help you get better at programming once you learn how different these two languages are, even though a lot of people put them in the same bag.