When to use C over C++, and C++ over C?
I've been introduced to Computer Science for a little over a year now, and from my experience it seems that C and C++ are both considered to be "ultrafast" languages, whereas others such as Python and such scripting languages are usually deemed somewhat slower.
But I've also seen many cases where a software project or even a small one would interleave files where a certain number n of those files would be written in C, and a certain number m of those files would be written in C++.
(I also noticed that C++ files almost always have corresponding headers, while C files not so much). But my main point of inquiry is to get a general sense of intuition on when it is appropriate to use C over C++, and when it is better to use C++ over C. Other than the facts that (1) C++ is object-oriented whereas C is not, and (2) the syntaxes are very similar, and C++ was intentionally created to resemble C in many ways, I am not sure what their differences are. It seems to me that they are (almost) perfectly interchangeable in many domains.
So it would be appreciated if someone could clear up the situation! Thanks
Using C inline in C++ code is usually for certain modules that need to be highly optimized, do very low-level work closer to the hardware, or are critical for integrity of the data or even human safety and need to be auditable and proven correct. Rather than doing it all in C, the bulk of the project can take advantage of C++ features for flexible designs, while getting the benefits of C's tightness in those places where it is needed.
@kylben: Many C++ guys will tell you: (1) Performance is not a reason to drop to C (perhaps to avoid `virtual` and a few other features which prevent optimizations, but e.g. non-`virtual` classes aren't inherently inefficient, and templates are a powerful abstraction tool that can actually lead to *more* efficient - e.g. `qsort` vs `std::sort`). (2) High importance of correctness is a reason to use C++ (typesafety, `const`ness, `private`, RAII to make resource management manageable, etc.) over C. Or for that matter, use Ada or something in the first place.
delnan, I didn't say they drop to C because C has inherently better performance, but so they can optimize it. A programmer very familiar with how the compiler turns C into asm can write C code that is optimized better than what the compiler can do, without having to write raw assembly.
As to C++ producing more optimal code, that may be true for naive code written on design and maintainability criteria, but there is nothing in C++ that can't be done in C with enough extra code (aside from access limitations, which can be gotten around in C++ anyway), and a really good C programmer can write anything C++ can do better than C++ can do it, if its worth the extra effort.
@Pubby8 I disagree with this. If I am working on a .c file and I see people do this, I tend to mentally flag them as not knowing what they're doing. For example, there's no need to cast from `void*` to another pointer type in C code, it's very distracting and typical of people who don't know C.
@kylben: (You might want to learn to properly address others in your comment replies, so they have a chance to actually _see_ them.) That "a programmer very familiar with how the compiler turns C into asm" would work for C++ just as well. But that's simply irrelevant: If you want to dabble in asm, just write asm instead of having a compiler create it from some other language. The way it does this might change with every compiler update, after all.
And if you believe C++ code needs to be naive in order to outperform C, then you might want to have an actual look at the STL. (Hold on to your hat, though, because if anything is naive here, it's your uninformed prejudices.) Also: For five decades none of the many "really good C programmers" have come up with a way to write an efficient generic sort algorithm. Of course, that shouldn't hinder you from expecting it to happen anytime soon, but the rest of us will, meanwhile, resort to the STL for combined speed and expressiveness.
@Dark Templar You can probably get 1000+ threads, essays and papers regarding this very topic if you Google. Likely on this site as well.
In my humble opinion... you use C when you want to, for me: C is much more simpler and easier to use than C++ ... C++ might look like a "C With classes", but it's not anymore, now it's a very complex language, with things like Virtual Constructors and Templates.
You pick C when
- you need portable assembler (which is what C is, really) for whatever reason,
- your platform doesn't provide C++ (a C compiler is much easier to implement),
- you need to interact with other languages that can only interact with C (usually the lowest common denominator on any platform) and your code consists of little more than the interface, not making it worth to lay a C interface over C++ code,
- you hack in an Open Source project (many of which, for various reasons, stick to C),
- you don't know C++.
In all other cases you should pick C++.
I would also add that C++ with exception model sometimes brings more trouble than it's worth, for say, OS kernels. At least that's the general feeling I have gotten while reading about stuff.
@Coder: I suppose that, in an OS kernel, you simply must not call any functions that might raise exceptions. Since there is very few stuff in the language/std lib that throws exceptions, and since most of it (like `new`) is ruled out in an OS kernel anyway, I do not see how this applies.
Note, however, that Comeau C++ produces C as output, and they provide porting to almost any C compiler, so essentially anything that supports C can also support C++, though it might require enough more resources, that on a small system it would have to be run as a cross-compiler (even though the C compiler ran natively).
@Jerry: That is true. However. Comeau has to be ported to targeting a specific C compiler. Unless you are targeting GCC, in which case you already have a reasonable C++ compiler, you need to plan that cost. Porting is offered by Comeau comparatively cheap, but not for free.
I don’t agree with point 3 – why can’t you use C++ here? You also didn’t say *why* you’d pick C++. An executive summary would be nice, especially since all other answers got this so phenomenally wrong. Since there are already good answers on other questions – *cough* – link to one if you’re lazy. ;-)
I'd add one more important reason, why Linux Kernel is in C. C is lingua franca of the programming world, allowing everyone with moderate skill to start coding right away. C++ after first hundred lines of code starts getting "flavors" and 10,000 lines into the project you don't code in C++ any more, just some specific meta-language you have built using C++ templates, class structure and design patterns. And anyone joining the project needs to learn that meta-language from scratch, taking a good month to catch up.
@SF: C is the lingua franca? That's new. Or rather, very old. Maybe if you only converse with people who haven't learned new languages for the last 20 years, but I'd say that C knowledge isn't very common anymore.
@SF.: As I have written elsewhere, I've been in projects that amounted to _millions_ of LoC, and saw very few meta-stuff compared to C projects with their inevitable and ubiquitous macro hackery. (OTOH, the ability to create EDSLs when needed can be an incredibly powerful tool in your box.) As for C being the lingua franca: I'd rather stick to my term that it's the lowest common denominator. And I wouldn't want people with moderate programming skills hacking at an OS kernel.
@SF Take this with a grain of salt, but C is to programming what Latin is to the scientific community... When it comes to being "lingua franca" that is. It's still a useful language.
@Max: I completely disagree. C is a useless language, unless some insurmountable practical barrier prevents the use of C++.
The only thing I would add to this is that C can be the only option when you are faced with draconian memory limitations.
@Buttons: No, usually they don't. They do automate some tedious tasks, though, like resource cleanup, or dynamic dispatch. If you are short of resources, why would you dismiss this advantage? I agree, though, that it is helpful to know the general "resource costs" associated with certain C++ features (for example, virtual functions) and make your decisions about which ones to employ when and where based on that knowledge.
@sbi Do you have a citation? Are you saying that C++ programs usually use _less_ memory than C? Of cource C++ programs _can_ use less memory, but that's why I said usually.
@Buttons: It was you who made a claim ("C++ needs more memory"), so it should be you who backs that up. And, no, I am not claiming that C++ needs *less* memory. What I'm saying is that *features* cost, no matter whether the compiler implements them for you (virtual functions) or you do them yourself (array of function pointers).
One thing no one mentioned is that C has a simple and well-defined ABI, which is what makes it easy to interface to other languages with just a few assembly instructions. That is (IMO) the most convincing reason to use C, in a compatibility layer for example.