C and C++ specific problems

There are some features of the C and C++ languages and the associated build process that often lead to problems.

Preprocessor

C and C++ use a preprocessor to expand macro's, declare dependencies and import declarations and to do conditional compilation. In itself, this is quite reasonable. You should realise however that all of these are done on a textual level. The C/C++ preprocessor does not

This can make it difficult to track down missing declarations, it can lead to semantic problems because of macro expansion and it can cause subtle problems.

If you suspect a problem due to preprocessing, check out the preprocessor's manual (e.g. [CPP]) and let it expand your file for examination.

Strong systems dependency

C was developed for use as a systems programming language. C and also C++ can give you access to a lot of operating system functionality. Unfortunately, there are a lot of small but significant differences among various Unix systems:

Also, the size and representation of some of C's and C++'s basic types is dependent on the underlying system. As a C or C++ programmer, you should be aware of what things are explicitly undefined in the C or C++ standard, and thus are implementation (system or compiler) dependent. There are standard ways to overcome some of these problems, like using sizeof instead of the concrete size of the variable on the current system.

Weak type system

C and C++ have a type system, but it is very weak. You can do all kinds of conversions, many of which can be system dependent or meaningless. Also, the compiler can do some implicit conversions that may cause havoc.

Most errors due to the weak type system can be caught in the bud by doing static analysis early; see the section called Using the compiler's features.

Explicit storage allocation and deallocation

In C and C++, you have to explicitly allocate and deallocate dynamic storage through malloc and free (for C) and through new and delete (for C++). If memory (de)allocation is done incorrectly, it can cause problems at run time such as memory corruption and memory leaks (the memory use of a program keeps on increasing during execution).

Common errors are:

These errors are difficult to correct without using proper tools; see the section called Memory allocation debugging tools.

Name space pollution

In C and C++ programmers commonly do not to try to prevent name space pollution (name conflicts).

Incremental building/linking

C and C++ code can be built incrementally; usually make is used to specify dependencies among files for a build. If a Makefile does not specify dependencies properly, you can end up with executables linked to old versions of modules which can be buggy or incompatible with recently introduced changes in other modules.