I know this opinion is quite heretical in the current programming climate, but C has some serious problems as a language for anything but the most low-level code.
- C is not memory-safe There is nothing in C that prevents a program from scribbling on random bits of memory. This is a task left to the OS, which must sandbox processes to maintain memory integrity. This works, however it makes interprocess communication much more difficult than necessary, leading to byzantine systems such as CORBA.
- C cannot be garbage-collected efficiently Since integers can arbitrarily be casted to pointers and pointer arithmetic is possible, it is impossible to determine what areas of memory are in use by a C program. The Boehm GC can be used to a certain extent in C programs but cannot guarantee total collection. This leads to an entire class of memory bugs impossible in high-level languages.
- C has poor support for dynamic data structures The fundamental collection type in C is the static array, leaving all higher-level data structures to be reimplemented every time one is needed.
- C is weakly typed Typing is barely enforced in C, encouraging poor design.
- C is difficult to optimize Due to its low-level nature, there are very few clues to the compiler as to where data structures and algorithms can be optimized or parallelized.
C++ adds dynamic data structures in the form of the STL, but does little else to correct the major flaw, which is lack of pointer safety. C *is* a useful language for low-level code such as hardware interfaces but should not be regarded as suitable for general programming.