C Specific Properties and Implementation


C also has the following specific properties:

  • Weak typing ? for instance, characters can be used as integers (similar to assembly)
  • Low-level access to computer memory via machine addresses and typed pointers
  • Function pointers allow for a rudimentary form of closures and runtime polymorphism
  • Array indexing as a secondary notion, defined in terms of pointer arithmetic
  • A standardized C preprocessor for macro definition, source code file inclusion, conditional compilation, etc.
  • A simple, small core language, with functionality such as mathematical functions and file handling provided by library routines
  • C discarded the well established logical connectives and and or of most other ALGOL derivatives and replaced them with && and ||, which
  • Were invented in order to make bit-wise operations (& and |) syntactically distinct ? C's predecessor B used & and | for both meanings
  • Never evaluate the right operand if the result can be determined from the left alone (Minimal evaluation)
  • C popularized the controversial decision to free the equal-sign for assignment use by replacing = with == (inherited from B).

C lacks features found in some other systems implementation languages:

  • No non-scalar operations such as copying of arrays or strings (old versions of C did not even copy structs automatically)
  • No automatic garbage collection
  • No bounds checking of arrays and allocated memory segments
  • No operations on whole arrays
  • No semi-dynamic (i.e. stacked, runtime-sized) arrays until the C99 standard (despite not requiring garbage collection)
  • No syntax for ranges, such as the A..B notation used in both newer and older languages
  • No nested function definitions (although some compilers provide them, for example, GCC)
  • No formal closures or functions as parameters (only function and variable pointers)
  • No generators or coroutines; intra-thread control flow consists of nested function calls, except for the use of the longjmp or setcontext library functions
  • No exception handling; standard library functions signify error conditions with the global errno variable and/or special return values
  • Rudimentary support for modular programming
  • No compile-time polymorphism in the form of function or operator overloading; only rudimentary support for generic programming
  • No support for object-oriented programming; in particular, no support for polymorphism, inheritance and limited (inter-module only) support for encapsulation, even though there are libraries offering object systems for C, and many object-oriented languages are themselves written in C
  • No native support for multithreading and networking, though these facilities are provided by popular libraries
  • No standard libraries for graphics and several other application programming needs

Although the list of built-in features C lacks is long, this has contributed significantly to its acceptance, as new C compilers can be developed quickly for new platforms. The relatively low-level nature of the language affords the programmer close control over what the program is doing, while allowing solutions that can be specially tailored and aggressively optimized for a particular platform. This allows the code to run efficiently on very limited hardware, such as mass-produced consumer embedded systems, which today are as capable as the general-purpose machines originally used to implement C.

A number of the above missing features are available through the use of third party libraries. Most object oriented functions include a special "this" pointer, which refers to the current object. By passing this pointer as a function argument in C, the same functionality can be performed in C. For example, in C++ one might write:

stack->push(val);
while in C, one would write:
push(stack,val);

where the stack argument of C is a pointer to a struct which is equivalent to the this pointer of C++, which is a pointer to an object.