CFO: Why C?

From: VBDis (vbdis_at_aol.com)
Date: 09/01/03


Date: 01 Sep 2003 01:11:45 GMT

No doubt, C is fast, portable, and available everywhere.

Really???

My answer is NO, with regards to most of the pretended advantages of the C
language.

How can a language ever be slow or fast, or more or less portable?

C programs can be as fast as a compiler can make them, not more or less than
programs in other languages. What makes some other languages slower than C is
the runtime system, at best, which may include some more overhead like the
garbage collection built into Java. But the translation of application source
code into executable code is not affected by the choice of a specific language.
In contrast it takes much more time to compile C code, as opposed to other
languages, because the C syntax is hard to parse, ambiguous, and typically many
related (header) files must be processed for every single C source file. That's
why C is not a good choice, with regards to development turn around time.

C also is not more portable than any other language, in contrast it requires
much more efforts to make C code really portable, as is required for other
languages. And C itself is not sufficient for writing portable code, much more
tools are required to build any C program or library, like configure. But I'll
discuss the configure topic in another thread, this procedure is not only
related to the C language.

The availability of C compilers also is no valid argument, since a compiler for
C is much harder to implement than a compiler for other languages. In fact
processors for 2 languages must be implemented, since no C code can be
translated without preparing the sources with the preprocessor. For other
languages usually a single scanner and parser is sufficient instead. Everything
apart from scanner and parser is common to every compiler, for every language,
and that's why e.g. gcc can be used to translate more than only C code.

There exist more reasonable disadvantages of C, resulting in many attempts to
cure some deficiencies, like Java, C++ or C#. But why then is C still used for
most free software, if there exist languages which claim to be better than C?
IMO the only valid argument is the simplicity of the C language, which suggest
to use C for teaching programming at all. But every C coder must admit that C
is unusable for any application without the huge C standard library, and when
one recognizes this disadavantage of C, then it's too late to move to a
different language. Even if other C-ish languages try to simplify such a move,
by preserving much of the C syntax, the many bad habits from hacking C code,
and the already collected experience with the C library, will prevent most
coders from moving to other languages. And since none of the C-ish substitution
languages could break with the bad and almost inappropriate C syntax, none of
these languages was accepted as a "better" standard language.

So I'll take it as given that C will stay the most popular programming language
in the non-commercial area. But in business, where time is money, many
companies use different languages or at least development tools, which make the
software development effectively safer, faster and cheaper. But in the hobbyist
area time is not a factor, neither the time to write the first version of some
program, nor the time to document or update that first version, nor the time
required to debug that code, nor the time to make the code portable. I'll only
try to give you an idea of the improvements, which other languages can provide
to an software developer.

The most important issue IMO is type safety, which is very weak until
inexistent in C. When I translated C code into a different language, or only
used the type checking features of an C++ compiler, I could find a lot of
lurking bugs and inappropriate data types in any existing C code. Who ever
claims that C is fast, would be surprised by seeing how easy it is to write
inefficient code in C, which results in many implicit type conversions with
every assignment to a variable of an integral data type. Warnings about mixing
signed and unsigned data types usually are ignored, and the compiler either is
instructed to ignore possible overflows, or will silently extend all operands
to the next larger data type. Of course the choice of a different language will
not cure this problem, but it may encourage the coder to think more about the
use of immediately compatible data types. Since C requires type casts all the
time, it's so easy to add some unnecessary type casts in many places. Such type
casts can not only slow down the code, they also effectively prevent any type
checking, which otherwise could reveal many coding errors just at compile time.
Using enums instead of #defined constants also would prevent the inadvertent
use of inappropriate values. C++ can offer more type safety, at no extra cost,
when macros are converted into inline functions. But nobody is forced to use
such cheap means for writing safe and checkable code in C, and if you insist in
making all your errors yourself...

Another issue are the C-style type declarations, which are hard to read and
also hard to parse for the compiler. Ever tried to decode the type of a
callback procedure, as passed as an argument to a subroutine? Or a list of
variables, with various type modifiers? Which parts then are common to all
members, and which specifiers belong to a specific member? What are typenames
at all, and where reside the names of procedures or variables in a lengthy
declaration? With only a different declaration syntax it would be much easier,
for you or any tool, to extract the declarations of data types, procedures and
variables from some source code or header file. If you ever tried to port some
code, and came across undefined symbols, you'll know how comfortable it will be
if all declarations can be extracted easily, even if they are ignored by the
compiler due to some inappropriate #if's?

Argh, those header files! Who has not already been swearing, on the difference
between the declaration and definition of global variables? Adding "extern"
variables to an header file is easy, but in which file are those variables
defined? And are the data types in the declaration and definition really the
same? A real nightmare in many larger projects :-(

In Delphi, or Object Pascal Language (OPL), I like the "set" type, which cures
a common deficiency of C. Most coders have already been struggling with flag or
option words, where every bit has a specific meaning. In many cases two sets of
constants are defined, one for the ordinal values of the options (1, 2, 3,
4...), and one for the bitmasks in the composite values (1, 2, 4, 8...), with
explicit conversions between both representations of the same option in many
cases, or inefficient switches or cascaded if's to check the value of specific
bits. Consider the isascii() and similar tests, which require a careful layout
and population of the chartype array, and the related constants and macros in
C. In OPL such collections of bits can be constructed from any enum, from which
the compiler not only makes the layout of the set variables, but also provides
all set operations like complement, union and intersection. Insert or reorder
the option values? No problem, only update the enum as desired, the compiler
will do the rest. No inadvertent wrong constant names or duplicate use of the
same bit, no gaps in the set variables, and (optional) automatic adjustment of
the size of the set variables, depending on the number of elements in the enum.
The implementation of such sets and set operations is not slower than what one
would write in C, and sometimes even faster when appropriate machine
instructions can be used, which will hardly ever be created by a C compiler.

Okay, okay, all that "can be done in C as well". But in other languages it can
be done in a safer or more convenient way, with a reduced risk of inadvertent
coding errors, because the compiler or the IDE can immediately check and verify
the use of every single operator or identifier. Have a look at the many style
guides, which describe recommended coding practices that shall prevent you from
stumbling into the many known C traps. In other languages it's easier to
circumvent such traps, because there the compiler won't let you make many
obvious errors. Using C++ instead of C will already be a big step towards
writing safer code, if you only are willing to use the extended features of
that language.

And if I couldn't convince you, can you give me life examples of cases and
constructs, where C is better or faster or more portable than other languages?
No, I don't want to know what's bad in other languages, I only want to know
what's so unique in C, inavailable in any other language.

DoDi



Relevant Pages

  • Re: Why C?
    ... > C programs can be as fast as a compiler can make them, ... > programs in other languages. ... > lurking bugs and inappropriate data types in any existing C code. ... With only a different declaration syntax it would be much ...
    (comp.os.linux.development.apps)
  • Re: Why do folks implement statically typed languages?
    ... The languages discussed are extremes. ... It allows the compiler to prove that your data-manipulations are ... an IDE for a dynamically-typed language can ... to IDEs in dynamically-typed languages. ...
    (comp.lang.scheme)
  • Re: arithmetic on a void * pointer
    ... Using norms from the realm of natural languages isn't necessarily ... the sizeof a void pointer is the sizeof the smallest unit of memory. ... It would be nice to think, however, that both compiler writers *and* ... here the Register. ...
    (comp.lang.c)
  • Re: python philosophical question - strong vs duck typing
    ... I actually stole the classification of continuums from a Python wiki ... Dynamically typed languages like Python keep, ... the coercion of floats to ints via the + operator, ... the compiler writers think so. ...
    (comp.lang.python)
  • Re: Why is C good??? any experts?
    ... it to maintain someone else's code is a completely different matter. ... > hodge-podge of exported subroutines and messy global variables. ... Compilers and, to a lesser extent, languages ... For example, to compute any algebraic expression, a compiler will ...
    (comp.lang.c)