Monday 18 February 2013

Why is the C preprocessor so bad? I mean...really bad

The C programming language is 40 odd years old. In the last
two decades, the number of new programming languages has raced
ahead - each with their own look and feel.

C is a low level language - as CPU speed increases have stagnated,
people have looked at C for more gains in performance. C++ to a large
extent improves on C, and negates much of the need for the preprocessor.

But one has to laugh at how much attention is given to compilers,
optimisations, libraries and standards. The preprocessor is treated like
a diseased lovechild.

In all these decades, the preprocessor has barely gotten any feature
enhancements - except for varargs and the # and ## operators.

What is it missing? Well, for one, *intelligence*. Anything. Please.


#include "filename"


Such a great function, but so badly designed. What is the one
thing every serious application does? Uses some form of autoconf,
so you can do:


#ifdef SOMETHING
# include "filename"
#endif


Why cant that be in the language?


#include_only_if_exists "filename"


There. That wasnt hard, was it?

Ok, so lets try one more. Assume a header file defines a value, lets
call it REG_R0. Another header file defines an enum for REG_R0. Consider
the following:


#define REG_R0 0
enum { REG_R0 = 0 };


Of course thats a syntax error above. We can do:


#define REG_R0 0
#if !defined(REG_R0)
enum { REG_R0 = 0 };
#endif


If that enum appears in a header file, we have no way to put the #if statement
in there. We might do something like:


#define REG_R0 0
#include_but_hide REG_R0, REG_R1, ... "filename"
#endif


This might mean, pretend the specified values are not defined for
the duration of including filename, so we can hide and avoid the
syntax error that will result.

Why do I care? Well, DTrace is fighting issues with ARM register names
with the "ucontext.h" file which seemingly wants to define register names
via an enum. I havent worked out how to resolve this, portably
and at the point of issue (rather than modify every source file to
change the way #includes are done).

Really, every language implements string and file parser as the
day-1 feature, and then adds bells and whistles for the rest of its
life to handle this.

C, being a "portable assembler" chooses to ignore the compilation
environment, and expects every developer to build inconsistent tools
because of the shortcomings of the preprocessor and environment
detection.

Why cant we do something like in Perl?


#if $ENV{COMPILER_FLAGS} =~ /-O3/
...
#endif


Oh well.

Post created by CRiSP v11.0.15a-b6542


No comments:

Post a Comment