163

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

Anonymous
  • 3,566
Dark Templar
  • 6,323

12 Answers12

185

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++.

sbi
  • 10,052
88

There are a few reasons to prefer C. The main one is that it tends to be more difficult to produce truly tiny executables with C++. For really small systems, you're rarely writing a lot of code anyway, and the extra ROM space that would be needed for C++ rather than C can be significant.

I should also add, however, that for really tiny systems, C has problems for exactly the same reason, and assembly language is nearly the only reasonable choice. The range of system sizes within which C really makes sense is quite small, and shrinking constantly (though I'll admit, fairly slowly).

Another time/reason to use C is to provide a set of functions that you can bind to from essentially any other language. You can write these functions in C++ by defining them as extern "C" functions, but doing so restricts those functions to presenting an essentially C-life "face" to the world -- classes, overloaded functions, templates, and member functions, etc., need not apply. This doesn't necessarily restrict development to C though -- it's perfectly reasonable to use any and all manner of C++ features internally, as long as the external interface looks like C.

At the same time, I have to say that @Toll's answers (for one obvious example) have things just about backwards in most respects. Reasonably written C++ will generally be at least as fast as C, and often at least a little faster. Readability is generally much better, if only because you don't get buried in an avalanche of all the code for even the most trivial algorithms and data structures, all the error handling, etc.

Templates don't "fix a problem with the language's type system", they simply add a number of fundamental capabilities almost completely absent from C and/or C++ without templates. One of the original intents was to provide for type-safe containers, but in reality they go far beyond that -- essentially none of which C provides at all.

Automated tools are mostly a red herring as well -- while it's true that writing a C parser is less work than writing a C++ parser, the reality is that it makes virtually no difference in the end. Very few people are willing or able to write a usable parser for either one. As such, the reasonable starting point is Clang either way.

As it happens, C and C++ are fairly frequently used together on the same projects, maintained by the same people. This allows something that's otherwise quite rare: a study that directly, objectively compares the maintainability of code written in the two languages by people who are equally competent overall (i.e., the exact same people). At least in the linked study, one conclusion was clear and unambiguous: "We found that using C++ instead of C results in improved software quality and reduced maintenance effort..."

Jerry Coffin
  • 44,795
24

The differences between C and C++ have already been enumerated in detail here. While sometimes people may have legitimate reasons for choosing one or the other (C++ for OOP or C when they feel like C++'s extra features introduce undesirable overhead, for example), in my experience it usually just comes down to preference. What do the people working on this file know better and like better? I believe this is the reason most of the time, since it's true that these languages both tackle performance critical applications.

(Side-note: Check out Linus Torvads' rant on why he prefers C to C++. I don't necessarily agree with his points, but it gives you insight into why people might choose C over C++. Rather, people that agree with him might choose C for these reasons.)

Casey Patton
  • 5,241
13

The main problem missing from the existing answers (as of the time of this posting) is the choice.

It's simple. If, for some utterly irrational reason, you feel that exceptions aren't worth the overhead, then you don't have to use them. You can still have templates, and RAII, and the Standard library, and never write a single "throw". The same goes for templates. If, for some reason, you feel they cause irrevocable (and actually important, which it is only on embedded) executable bloat, then surprise- you can use void* and sizeof(T) all day too. Nothing forces you to use any of the C++ features over C.

That's why C++ is an inherently superior language- you can cherry pick the features you want, and fall back to C-style programming when you dislike a given feature. Therefore, given that C++ is everything C is and more, it's an obvious fact that C++ is a superior language. Suggesting otherwise is like trying to suggest that 4 is greater than 5.

DeadMG
  • 36,914
9

Bjarne Stroustrup maintains a list of applications and companies that use C++; you can argue about procedural vs OOP programming all you want, but you cannot argue with industry results over the last 20 years.

C++ is commonly used for large-scale, multi-man, complex projects where separate people need to work on modularised components. You can build and maintain modularised code in C, of course, but the inherent OOP nature of C++ leads to superior modularisation, testability, and code-reuse.

The C++ standard library (STL), in itself with just vectors and maps, is reason enough to use C++.

C is commonly used for embedded systems.

I would personally use C only if there is some library that has only a C API.

tofi9
  • 211
9

I would say that the main reason why I would choose C over C++, is only when I would have to resort to "It this HAS TO BE 1000% stable" NASA kind of stuff.

C++ is ~99% C when we look at the performance, and it's a lot more productive. So even while in C you can write code that will be faster than C++ (you can use a subset of C++ without exceptions, virtual, streaming, abstractions, etc. as well, but that's basically C), the time to optimize every damn thing while STL is tested and does that already, would cost you more than the tiny performance gain you might achieve, or sacrifice because STL algorithms have been written by groups of experts, and you're probably not an expert in everything.

On the other hand C++ has a ton of abstractions. When under circumstance they leak, this gets you into trouble. And there are few people who know 100% of C++ gotchas, while, I guess, there are more that know all C gotchas, so writing a solution where every step is fully understood by all members of a team is a lot easier in C.

Example: Do you know when shared_ptr<smthn> will overflow its reference count, will it throw an exception? Things like these are not cool when Shuttle has to reenter the atmosphere, at least I guess so.

Also, exception handling is very, very hard compared to error codes. It's hard to see if the class is 100% exception safe, and easy to get into leaks. A lot of high rep people have expressed this opinion.

Allen
  • 101
Coder
  • 6,978
9

Things about C++ that make C programmers nervous

There's a lot of magic happening under the hood; constructors, destructors, virtual methods, templates, etc., can make C++ code a lot easier and faster to write than the equivalent C code, but harder to understand and reason through (depending on how well you know C++ and its associated conventions). Something as simple as Foo newFoo; may invoke a lot of code, depending on how the constructor for class Foo (and any classes it depends on) has been defined. This is also why the convention is to write ++it instead of it++ when iterating through a container, since postfix ++ often involves an expensive copy operation.

Depending on what you're doing, there can be some non-trivial overhead, especially for simple tasks. Take the following two programs, the first in C, the second in C++:

/* C version */
#include <stdio.h>
int main(void)
{
  char greeting[] = "Hello, world";
  printf("%s\n", greeting);
  return 0;
}
/* end C version */

/* C++ version */
#include <iostream>
#include <string>
int main(void)
{
  std::string greeting("Hello, world");
  std::cout << greeting << std::endl;
  return 0;
}
/* end C++ version */

Identical behavior, not a whole lot of difference in terms of source, but on the SLES 10 box I work on with gcc 4.1.2, the former generates an executable of ~9kb in size, whereas the second takes over 12.5kb (no optimization), almost 28% larger. The C++ string type is a lot easier to work with IMO than the C string library, and C++ streams are a lot more flexible and customizable than C streams, but for really brain-dead code like this, they may not be worth the overhead.

C++ is a huge language compared to C, with some extremely complex semantics. It takes a lot longer to get proficient with C++ than C, meaning a lot of people who claim to know C++ don't know it as well as they think they do.

Things about C that make C++ programmers nervous

C is not a secure programming language by any stretch of the imagination; no bounds checking on arrays leads to lots of exploitable behavior (be it through the now-dead gets function, or through scanf with the %s and %[ conversion specifiers). C++ at least gives you containers that throw exceptions if you try to access outside their currently defined range; all C gives you is (if you're lucky) a segmentation violation.

Memory management in C is very labor-intensive and error prone, compared to the tools C++ provides you. If you're building your own container, you're responsible for matching up all the malloc and free calls, making sure allocations are successful, backing out any partial allocations in the event of an error, etc. In C++, you just add items to or remove items from the container. If there's a problem, an exception will be thrown.

Similarly, error handling in C is a pain in the ass compared to the tools C++ provides (namely, exceptions). What's really fun is when you've allocated a bunch of memory and then hit a wall in your processing; as you have to back out, you have to release that memory in the right order. With C++ and RAII principles, this is (relatively) easy to do.

So when do I use one over the other?

If what you're writing is a bog simple, read it / muck with it / get rid of it application, whose behavior can be described cleanly in terms of inputs and outputs, and performance matters, then prefer C over C++. Otherwise, prefer C++

John Bode
  • 11,004
  • 1
  • 33
  • 44
6

C is portable assembly with better syntax, yielding the programmer full control of everything.

C++ on the other hand, does a lot of funky magic (virtual functions, overloading, automatic conversion, etc etc) which may not be desirable when you want to make sure you:

  • don't use more memory than you want to
  • don't access memory pages willy nilly (the vtable can be anywhere)
  • don't invoke to much code accidentally

And want something really simple to work with, since you're focused on performance.

It just has no surprises, and that's very valuable.

If you want to (and I recommend it), read the JSF coding guidelines on what you need to think about when writing C++ for military avionics control. It's a lot of traps in there that you need to be aware of, and it may catch you out. Bjarne was part of that document, so he knows what it's about.

Also, C compiles like a scalded troll struck by lightning. C++, OTOH, was probably sponsored by the same people who invested in SSD companies . :)

(Personally, I'd prefer C++ though, but I don't like it...... either. ;-P)

nairware
  • 179
Macke
  • 2,576
2

(given you have equal familiarity with both languages)

Go with C++ unless there is no C++ compiler for your platform. You can write C++ code without whatever portion of the language you don't like (no classes, exceptions, virtual inheritance, whatever personal restrictions you wish to apply), and then at some time in the future, if you decide you want some of those features after all, then you can easily use them. Nothing in C++ prevents you from writing C-style code.

(given equivalent toolsets and developer knowledge) There is no reason to choose C over C++ provided your platform has a C++ compiler. You can simply limit yourself to the subset of the language you wish to today, while leaving the door open for extension later.

anon
  • 1,494
1

Both languages are excellent. I think a number of posters have detailed the strengths and the various uses for each. I will simply add this:

I see the C language perfect in 4 areas: 1) I think it's the best language to use when first learning any type of programming [combined with some Assembly and knowledge of machine code], 2) it's great for writing drivers, 3) embedded software, and 4) system software at the lowest level.

C++ is an object-oriented language, but it can also be procedural (very much in the way of C). If you're working on large-scale projects, GUI-based software, gaming software, and other types of graphically-intensive software, then I find C++, Java, or even Objective-C to be your best choice. However, there is plenty of command-line programs or system software where you might find C++ to be as good or better than C.

0

In my opinion there is one point missing in this discussion: It is simpler in C to provide a stable binary interface from a library. Both for usage with other languages as well as C++.

In C++ different compilers use different name mangling so consumers of a library compiled with a different compiler from the library might have issues using it. With C the binary interface, usually, is standardized for the platform.

I know that compilers nowadays often have switches to produce gcc-compatible things, but that doesn't always help.

I observe this on Solaris relatively often. The distribution and different software vendors typically use Sun Studio as, especially on Sparc systems, it often provides better results. Man open source projects are written with gcc-specific code though. Can be quite some pain to get those working together.

johannes
  • 3,611
0

C is probably preferable to C++ when the C code is generated (e.g. in implementations of higher-level languages). For example, there are several Lisp-like compilers which emit C code (e.g. Chicken, Scheme48 ...), but I know none which emits genuine C++ code (my MELT tool emits C++ code, but I won't call that code genuine C++ code, it uses very few C++ features).

C code is also easier to prove semi-automatically. Static analyzers like Frama-C (where you annotate your C code with ACSL comments to help the prover reason about your code) are available for C, but not that much for full C++11.