#1 Why is C so appealing?
Posted: Sat Sep 05, 2009 10:22 am
This was written for the Sveit forum, but I wanted to give it slightly wider audience, despite the fact that me and Adam are the only two programmers here.
Why is C so appealing? A counter point to “Why does C Hate Me”
Ace Pace
C is a quirky little language that seems to evoke quite a few strong emotions from people. Mostly these people are new to the language and don't understand why it's built the way it is. Some of these emotions come across bad usage of the language, using it to solve problems it wasn't meant to solve.
A point to consider about C, language syntax is covered in 15 pages, the entire verbose standard is 556 pages. When K&R set up to define the language, they managed to do it in 272 rather large font pages. In comparison, the C++ language standard I can find comes out at around 1326 pages. What am I trying to say here? C is a rather small, concise language that precisely defines itself.
Now to actual matters of the language, C defines it's core capabilities by it's stated goal of System Development. These core capabilities are different to most programmers, so someone will probably come and argue against me that I'm missing some cherished feature.
Those core capabilities start with a strong mapping of data types to their memory representation. If I define a variable in C, I can estimate with a fairly high level of confidence the exact byte representation. When we step into memory concepts, I know precisely what a pointer is and what it points at. This is in marked contrast to data types in say Python, where a reference is an object in it's own right!
Another strong characteristic of C is that instructions are “plain”. What do I mean by this? Let us examine the following line of code.
int cbFunctionSize = cbByteCode + cbStackSize;
I am pretty sure I will not find a situation where the above instruction does not add two numbers together*. This pretty clear understanding of the code is in marked contrast to the situation with some more advance languages that allow things such as operator overloading.
*Obviously, I'm ignoring macros.
These two characteristic together make for the description of C as a “low level” language, with a strong mapping of code to binary.
Function declarations are another neat feature in C that many don't appreciate. Let us consider how we define an interface for a hypothetical BMP parser. We would have two files. One would be the public interface, BMPparser.h, and will include a variety of things such as function definitions, typedefs, hopefully quite abit of documentation. Another file(or files!) would be BMPparser.c, which would have somewhere around the top a directive of #include <BMPparser.h>. This file will have to fulfill the interface with actual functions, but can also modify things for itself (such as parameter names).
Why is this nice? Code readability. If I want to study an interface, I'll open up it's .h representation and go with that. In many other languages, such as C#, I will have no choice but to wade into the actual code and hope my IDE lets me ignore as much of the irrelevant stuff.
But Ace, we have IDEs nowadays that let you generate interface documents automatically! Yes, but that's just cover up for the fact there is no separation of interface and implementation. It's a weak mechanism that provides a band aid over the language.
Now I must take Curtis (writer of “Why does C Hate Me? Understanding C Behavior“) to task. His examples were lacking in understanding of the problem. His example of writing to memory that is not “yours” was a classic mistake in C. The problem is not that behavior is undefined, it's that the programmer did not understand his duty! Arrays in C exhibit some curious properties that make them very flexible yet very dangerous. Typed as arrays, they define a data type that contains a collection of sub-types in a contiguous section of memory. Yet if you consider the actual type you work with, what you have is a reference to the first cell in the area. A pointer. And pointers are not guaranteed to point anywhere legal and it is up to the programmer to make sure they point to valid memory.
In all fairness to C, I must add that the biggest mistake in C is one of it's most powerful and abused features, Macros. Macros are simply dumb and are the source of more frustrations as a C programmer than anything else.
________________________________
I feel I must add something that did not fit into the essay, because it had little to do with the language itself yet is C's greatest failing. I'm talking about stdlib.
To those that don't know what I am referring to, I am referring to the C Standard Library, a collection of 24 header files that define the common interface of all C programs.
This library is horrid. I can't find a single redeeming feature in it, from the lack of error handling, to ERRNO as a way of checking for errors to it's atrocious string handling. It is almost worth writing off C as a language to write anything meaningful that is also portable simply due to stdlib.
Why is C so appealing? A counter point to “Why does C Hate Me”
Ace Pace
C is a quirky little language that seems to evoke quite a few strong emotions from people. Mostly these people are new to the language and don't understand why it's built the way it is. Some of these emotions come across bad usage of the language, using it to solve problems it wasn't meant to solve.
A point to consider about C, language syntax is covered in 15 pages, the entire verbose standard is 556 pages. When K&R set up to define the language, they managed to do it in 272 rather large font pages. In comparison, the C++ language standard I can find comes out at around 1326 pages. What am I trying to say here? C is a rather small, concise language that precisely defines itself.
Now to actual matters of the language, C defines it's core capabilities by it's stated goal of System Development. These core capabilities are different to most programmers, so someone will probably come and argue against me that I'm missing some cherished feature.
Those core capabilities start with a strong mapping of data types to their memory representation. If I define a variable in C, I can estimate with a fairly high level of confidence the exact byte representation. When we step into memory concepts, I know precisely what a pointer is and what it points at. This is in marked contrast to data types in say Python, where a reference is an object in it's own right!
Another strong characteristic of C is that instructions are “plain”. What do I mean by this? Let us examine the following line of code.
int cbFunctionSize = cbByteCode + cbStackSize;
I am pretty sure I will not find a situation where the above instruction does not add two numbers together*. This pretty clear understanding of the code is in marked contrast to the situation with some more advance languages that allow things such as operator overloading.
*Obviously, I'm ignoring macros.
These two characteristic together make for the description of C as a “low level” language, with a strong mapping of code to binary.
Function declarations are another neat feature in C that many don't appreciate. Let us consider how we define an interface for a hypothetical BMP parser. We would have two files. One would be the public interface, BMPparser.h, and will include a variety of things such as function definitions, typedefs, hopefully quite abit of documentation. Another file(or files!) would be BMPparser.c, which would have somewhere around the top a directive of #include <BMPparser.h>. This file will have to fulfill the interface with actual functions, but can also modify things for itself (such as parameter names).
Why is this nice? Code readability. If I want to study an interface, I'll open up it's .h representation and go with that. In many other languages, such as C#, I will have no choice but to wade into the actual code and hope my IDE lets me ignore as much of the irrelevant stuff.
But Ace, we have IDEs nowadays that let you generate interface documents automatically! Yes, but that's just cover up for the fact there is no separation of interface and implementation. It's a weak mechanism that provides a band aid over the language.
Now I must take Curtis (writer of “Why does C Hate Me? Understanding C Behavior“) to task. His examples were lacking in understanding of the problem. His example of writing to memory that is not “yours” was a classic mistake in C. The problem is not that behavior is undefined, it's that the programmer did not understand his duty! Arrays in C exhibit some curious properties that make them very flexible yet very dangerous. Typed as arrays, they define a data type that contains a collection of sub-types in a contiguous section of memory. Yet if you consider the actual type you work with, what you have is a reference to the first cell in the area. A pointer. And pointers are not guaranteed to point anywhere legal and it is up to the programmer to make sure they point to valid memory.
In all fairness to C, I must add that the biggest mistake in C is one of it's most powerful and abused features, Macros. Macros are simply dumb and are the source of more frustrations as a C programmer than anything else.
________________________________
I feel I must add something that did not fit into the essay, because it had little to do with the language itself yet is C's greatest failing. I'm talking about stdlib.
To those that don't know what I am referring to, I am referring to the C Standard Library, a collection of 24 header files that define the common interface of all C programs.
This library is horrid. I can't find a single redeeming feature in it, from the lack of error handling, to ERRNO as a way of checking for errors to it's atrocious string handling. It is almost worth writing off C as a language to write anything meaningful that is also portable simply due to stdlib.