C++ vs. C

From Pin Eight
Revision as of 19:52, 6 July 2010 by Tepples (talk | contribs) (Minuses: What the f*** is char_traits?)
Jump to: navigation, search

The C++ programming language brings improvements over its predecessor C, but fans of other languages point out that C++ is still not perfect. Over a decade after the 1998 standardization of the C++ programming language, the C++ vs. C debate continues.


Compared to C, C++ has a bunch of new language features with little or no runtime overhead because they are translated to code equally as efficient as the equivalent C code:

  • namespaces
  • function overloading
  • type-safe new(std::nothrow)
  • STL, the part of the C++ standard library with containers and algorithms
  • non-virtual methods
  • references, needed by operator overloading

A few features are as efficient as C yet still rawther deceptive and easy to misuse because the "simple" syntax hides how much code is actually being generated:

  • operator overloading, when compared to separate functions
  • virtual methods, when compared to C function pointer tables
  • templates instantiated several times, when compared to using the preprocessor to instantiate multiple copies


C++ also has some features requiring possibly expensive runtime library support:

  • throw
  • the default version of new without std::nothrow, which throws std::bad_alloc
  • <iostream>

Templates have a couple drawbacks:

  • Type names in error message become far more difficult to interpret. Common implementations* may expand a template type name fully in diagnostic messages even if the source code accesses the type through a typedef. For example, an error message involving the std::string type is likely to provoke this reaction: "basic_string? I'm using C++, not BASIC! And what the fsck is char_traits?"
  • Programmers can lose track of for how many different type combinations they have instantiated a template, causing code size to balloon. There is a common extension called extern template allowing for explicit instantiation, but it's not in C++98, and not all compilers support it.

Exceptions (throw) also have a couple drawbacks:

  • Though exceptions have little to no runtime speed penalty in a modern C++ compiler, the size of the required library support might cause a problem on embedded or handheld devices with less than about a megabyte of RAM.
  • C++98 has no counterpart to the finally keyword of Java and Python. True, there isn't as much need for finally in C++ as in languages that rely on a garbage collector, given the idiom of allocating resources in constructors that C++'s deterministic destruction allows. But a method often still needs to restore the object's fields to a consistent state before eating or rethrowing the exception. C++0x addresses this by letting the programmer build a scope-guard with std::shared_ptr and lambda expressions.

On platforms without virtual memory, a program must be aware of possible out-of-memory conditions. The STL allows passing an allocator to all containers, but most implementations appear to exhibit undefined behavior when allocate() returns 0 like new(std::nothrow) does. I've been told one STL implementation can be built with nothrow in mind: STLPort.[1] EA created an out-of-memory-aware allocator.

The <iostream> library is another divisive issue. It was envisioned as a type-safe alternative to <cstdio>, but implementations are hairy, bloated, inefficient. Yet some C++ fanboys claim that anything using good old <cstring> and <cstdio> instead of new-fangled <string> and <iostream> isn't in the spirit of C++, whatever that means. They cling to item 2 in the second edition of Scott Meyers Effective C++ and ignore item 23 of his sequel ("consider alternative libraries"). It appears that Meyers eventually recognized that <iostream> is imperfect and removed item 2 from the third edition.

  • True, implementations are not the language, but a language is only as good as its best free implementation.

External links

  • C++ FQA Lite, offering a rebuttal to the fandom's C++ FAQ Lite