|
|
|
Is C a Vitamin? Yes, of course...
|
Category: C / C++
Date: 01.02.2008 08:05:54
|
This article is actually a followup for the entry of Ozgur Macit, on his blog called 'Is C a vitamin? He criticies the missing features of C, importance of C and the teaching of C for Engineering students.
Please go and read the referred article before this entry.
At first, let me congratulate Ozgur Macit for this professional entry. it's good to have references, even for a single blog entry, this gives a professionality and article like dignity. But this negative critisism bites me :) , I think there are many worng decisions and iniquity for C, so I've considered to follow up.
1) Readability (yes, it is Read'A'bility, not Readibility)
The deep mistake on the entry is, you are comparing C, the low-end of high level languages(this original definition is written by me :) ) with a very-high language, Python. They are so irrelevant that, they are for different purposes. This is from one of your references, "Comparison of programming languages", on wikipedia:
"Language: C
Intended Use: System
Design Goal: Low level access, Minimal constraint
Language: Python
Intended Use: Application, Educational, Scripting
Design Goal: Simplicity, Readability, Expressiveness, Modularity"
Although this article an wikipedia has many missing things, are there any similarity? No, right. Let's exploit wikipedia, for the purpose and deign goal of C:
"C is a general-purpose, block structured, procedural, imperative computer programming language developed in 1972 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system. It has since spread to many other platforms. Although C was designed as a system implementation language, it is also widely used for applications. C has also greatly influenced many other popular languages, especially C++, which was originally designed as an extension to C.
C is an imperative (procedural) systems implementation language. Its design goals were for it to be compiled using a relatively straightforward compiler, provide low-level access to memory, provide language constructs that map efficiently to machine instructions, and require minimal run-time support. C was therefore useful for many applications that had formerly been coded in assembly language.
Despite its low-level capabilities, the language was designed to encourage machine-independent programming. A standards-compliant and portably written C program can be compiled for a very wide variety of computer platforms and operating systems with minimal change to its source code. The language has become available on a very wide range of platforms, from embedded microcontrollers to supercomputers..."
Let me summarize the main goal of the C, the main purpose of use of C: Writing memory and CPU efficient programs, relatively easy to compile(fast compilation), easy to code near the level of assembly languages. It's so low-level that, you can imagine the assembly equivalent of the C code while you are writing the C code :)
I'm not so familiar with Python, but I know it's for a different purpose, with different pros and cons, with different(higher) level of programming.
If you want to compare C with another language, this must be Pascal, or Basic or whatever, but with the similar level, with the similar efficiency and similar purpose. You will see it's mostly Pascal, if you want to compare C with a language.
Now, go and see the comparison on wikipedia: Comparison of Pascal and C (http://en.wikipedia.org/wiki/Pascal_and_C)
Then, you may not say anything about C's readability. Readability is the primary benefit for whom uses C. You may not know Pascal, but you will see it's very similar to PL/SQL in the syntax. You have the begin-end blocks, if-then-end if, etc. It's very hard to read such a code, compared to the C equivalent, isn't it?
Also, from a simple Google search, you can find the links:
•
Top 10 Reasons Pascal beats C
•
C vs. Pascal
•
Why Pascal is Not My Favorite Programming Language
If you read them, you can see it's also very ridiculous to compare Pascal and C, because no way to have a better comment than:
"The question asked is: Which is better or more suited to a particular task ?
The answer ? There is no answer !"
And also I love the moral of the story:
"Bottom line is:
Choose the tool you are at ease with and it will serve you well. The C vs Pascal debate is a waste of time. "
(Both quoted from C vs. Pascal)
And maybe you will have a chance to understand how funny to compare C and Python, or Java or something like.
2) Orthogonality
The example ypu have given is not so strange, you can do the same thing with MALLOC kind of stuff, you know. You have addressed the problem of C doesn't have a native String type. That's what the higher-level languages like Java or Python do for storing a String: Dynamic allocation! Since the language does it automatically, it comes so simple for the programmer. You have the simplicity, but you lost the conrol, you lost the efficiency.
It's not he Orthogonality issue as you said:
"Programmer occasionally does not have chance to write a similar code for two similar instances of same problem in C. For this reason, C is said to be not orthogonal."
And let me write the similar code for the same problem that you addressed. You can
compile and run, it's working:
#include
#include
#include
char * double_str(char * s) {
int len = strlen(s) * 2 + 1;
char *t = malloc(sizeof(char)*len);
strcpy(t, s);
strcat(t, s);
t[len-1] = '\0';
return t;
}
int main() {
char s[] = "hello bilal!";
char *ret = double_str(s);
printf("%s\n",ret);
return 1;
}
3) Safety
• "Though type checking is done by compiler, programmer is free to make type casting."
Yes, that what we "the C coders" love. What's wrong with it? In C, the programmer have the power but he also have the responsibility.
• "C never and never makes index range checking. It is claimed that C encourages buffer overflows with this property in [2]. Same source gives a list of functions that may cause buffer overflow accidentally."
As I said, "In C, the programmer have the power but he also have the responsibility". Index range checking is not the problem of C, it's actually the problem of the compiler. I know some C compilers does index range checking, but actually it's disabled feature traded to have efficiency.
Consider a huge loop:
char *c;
...
for(i = 0; i < 999; i++) {
c[i] = i;
}
And the "sweety"(!) compiler adds the index range checking code:
char *c;
...
for(i = 0; i < 999; i++) {
if(i > index_range_of_c) { // whatever, the compiler knows
printf("Index range out of bounds: c[%d]\n",i);
return; // or exit();
}
c[i] = i;
}
and compare the execution time (and also compilation effort, not for this case but for general case) of each. Than come and say "Why don't C have index range checking? C is an evil."
• "Programmer has the memory! No safety check is done about memory allocation."
Yes. "In C, the programmer have the power but he also have the ..." :)
C let's programmer to write some code, not writes the code, generates the algorithm and does the job of programmer etc. like Java or Python.
• "You must not free same pointer twice - again accidentally, if you do you are in trouble. There is no internal mechanisms to avoid this. Programmer must always check the pointer while allocating and freeing memory."
If programmer needs to check it, he checks it. If the programmer knows what he is doing, no problem. For compiler, why bother and trade the performance for collecting the "garbage" of the programmer every time, so pump and exaggerate the code which will steal my machine cycles and memory?
4) Redundancy
"But like a lot of similar things it cannot be fully thrown out of language, because backward compatibility is needed."
Go and look the documentation of Java. You will see a lot of stuff that is deprecated, although, Java is a brand-new language (developed in mid 90's). C is an old language, yes, some functions have security problems or bugs, but it's normal and not so much.
“In many ways, the C language evolved into a collection of overlapping features...”
Overlapping features?? Yes C has overlapping features, but which "old" language doesn't have? The brand-new Java although have much more overlapping features and non-reliabilities. Go and look about it.
“... providing too many ways to say the same thing, while in many cases not providing needed features.”
C not providing needed features?? Oh no, why don't you find a psychiatrist, who can carefully listen and confirm you and what you are saying about C?
Yes a "White Paper" of Java can say that. I had always encouraged them to go and look about inside Java. :))
5) String type, Error Handling
Yes, these are considered as missing features also in C community. But one can do what he want with writing some more code and with some workaround, right?
6) Reaching Elements
"Another complaint about C is why do we have both . and -> to use for the same purpose. Firstly, they are not for the same purpose. '.' is structure offset and -> is used for dereferencing. Sure we should expect from compiler to take care of this difference or we can simply do not want to help the compiler to ease its job."
Why not? Is the compiler your enemy, or opponent? It seems to be a simple feature for compiler, but it's actually not easy to keep track of. Notice one of the main purposes of C: Easy, fast compilation. C is designed as it can be compiled also on limited environments.
"But in my opinion understandability of code increases with this small difference. Looking at the code we can easily see what is a pointer and we are dereferencing its indigrents and what is a name of a real structure. Let me say I never liked Java way of avoiding pointers."
I can't understand on which side are you but with two different identifiers '.' and '->' one can easily understand if it is a pointer or structure itself. It's more readable. Pascal has also just the '.', but it's just lack of readability I think.
7) goto statement
"James A. C. Joyce claims that using a goto statement is the only way of breaking out of nested for or while loops in [2]."
Yes, he now compared with PHP!! What about Pascal or Basic? And he says:
"A couple of examples should illustrate what I mean quite nicely. If you've ever programmed in PHP for a substantial period of time, you're probably aware of the 'break' keyword. You can use it to break out from nested loops of arbitrary depth by using it with an integer, such as "break 3"; this would break out of three levels of loops.
There is no way of doing this in C. If you want to break out from a series of nested for or while loops then you have to use a goto. This is what is known as a crude hack."
Yes, we appreciate Kernighan for providing us this hack :))
"In addition to this, there is no way to compare any non-numerical data type using a switch statement. C does not allow you to use switch and case statements for strings. One must use several variables to iterate through an array of case strings and compare them to the given string with strcmp(). This reduces performance and is just yet another hack.
In fact, this is an example of gratuitous library functions running wild once again. Even comparing one string to another requires use of the strcmp() function."
Dude, do you know how the "high-level languages" that you glorify does that stuff of 'String comparison'?? It's just the same of strcmp() at the lower-level, it must be, the compiler automatically does it, with even worse performance than C. Yes, in C, the "switch" statement does not allow strings, but even the "case of" statement in Pascal not. The features of brand-new, higher level languages fascinate you, but you even don't know what they are stealing from your brand-new GHZ'es of CPU's, GB's of RAM, and high-end hardware configuration.
I don't know who James 'whatever' is, but he seems to be a good candidate for being 'The Burlescon of C' :))
Note: Yes, goto statement lacks of readability, but nobody encourages to use it for most of the languages. It's not an issue for just C.
8) Enums
"C’s enum structure has a very significant and important problem which may be easily solved with object-oriented programming. If you use a name in an enum, you cannot use this name in another enum. If you use an object-oriented programming language like Java, you may put the same constant name inside different classes."
Yes, it seems from now on you are comparing C with Java. :)) Don't make me laugh... If you want OO stuff (with lot's of overhead of inefficient execution) go and use Java, Python or whatever, but don't say anything to C, it's just a structural language. Why don't you compare the OO features of 'your Python' and Java?
9) What C doesn’t have
"• Exception handling mechanism "
"• Function overloading "
Yes it doesn't. Nothing to say.
"• Specialized data types"
Object-Oriented features?? :-s
"• Garbage collection"
Consider the garbage of who? :)) C executes the code that it is responsible to, while the 'Glorious Garbage Collector" collects 'The garbage of the programmer' in other languages :)) Consider the overhead of the garbage collector, I will write a separate article about it later. I can't belive you are talking about a lacking
"garbage collector" under "Waht C doesn't have" :-s
The Conclusion
"C is not the evil in this story, I think. Just, it is not really proper for high-level programming. It must be used for what it is designed for.
Some bloody properties cannot be abandoned due to backward compatibility. Newbies always discouraged using these features by experienced programmers."
Let them be discouraged about it. They will be discouraged many times in the future. It's the reality of life :)) Notice I was discouraged when I have to create a huge "Integer" object for just storing a 4-byte integer value, and also lack of freeing that object from memory when I was done with that object, when I was learning Java.
"While coding in C, I feel myself in the middle of 70s while memory was so important and that I shouldn’t use a single byte if I really don’t need it."
Yes, sometimes you need to feel yourself like that. A good programmer always has to feel that. The whole CPU and GB's of cheap memory is not the right thing you may lean on. :)) Never!
Consider a Systems Programmer or Embedded Environment. That's why it's hard to do that stuff. That's why people can easily learn and develop applications in Java or C#, but not easily learn C and develop the deeper ones in C. I think that must be the difference of a person who got a 4-year Computer Engineering education.
"This makes me sick about C :)"
And this makes me love C :))
As an overall conclusion for your claim about "Is C the best language to teach as the first programming language, for Engineering students":
If you first teach students Java instead of C, you can never able to:
1) Teach them the C,
2) The importance and the purpose of C,
3) The importance of efficient programming,
4) The Systems Programming Concept,
5) The Embedded Programming Concept,
6) Even the assembly language :) (Already they are not able to learn assembly, even they are first learning C or other high-level languages)
7) The basic concept and principles of programming languages. Ex: You cannot teach what Java does when ou create an object with New(), if one doesn't already know about what MALLOC() does.
Since the aim of Computer Engineering study is the stuff above, It is mandatory to teach C, not only teaching the syntax of C, but also teaching the fundamentals of C and teaching them well better than other courses is mandatory.
But everybody who learns or who knows about Java or other higher level languages starts to criticise on C or the study of C. Sorry, but it's a bullshit.
"Is C a vitamin?" Yes, of course. Take one-a-day :)) or many, when you need, when you can't solve -as the majority of- real engineering problems(like Systems Programming,
Embedded Programming, Signal-Image-Voice-Speech Processing, and similar things requires design of efficient applications and algorithms) with higher level languages.
|
|
Links & References |
|
|
|
|
|