Best Practices for Programming in C
An anonymous reader writes "Although the C language has been around for close to 30 years, its appeal has not yet worn off. It continues to attract a large number of people who must develop new skills for writing new applications, or for porting or maintaining existing applications. This article provides a set of guidelines that can help you with your coding."
From the article:
for(i=0 to 100)
array[i]=0
Maybe I missed something but since when is that C?
When writing C++ you have full control over the use of dynamic type info, static or polymorphic method lookup, memory use and object lifetime, etc.
So, a good programmer can ensure that for performance critical code, none of those expensive features are used (selectively).
/..sig file not found - permission denied.
FYI, the article seems to be something like a company "basic C coding standards" rather than anything to do with what I understand as "best practices"; maybe a coding tips sheet for an introductory C programming class.
Larry
For example, for the C program that I'm writing right now, I decided to use GLib -- the base utillity library used by GTK.
I initially chose it for portability reasons, but soon discovered it had a wealth of cool stuff in it. In addition to providing the standard data structures (trees, hashes, linked lists), it also has a string type ( GString, ) which handles a lot of the string issues that C programmers get bogged down with.
A lot of the gotchas (buffer overflows, et. al.) mentioned in this article have to do with these string issues, and using GLib's GString data type has enabled me to avoid those.
There is another library similar to GLib, The Apache Portable Runtime, used in the Apache webserver, and also in Subversion.
In addition to all this, I'm using XML as the storage format for my program, mostly because libxml takes care of the file parsing issues so I don't have to.
Bottom line, choose your libraries carefully, they can make a world of difference.
Thomas
You should always check the return value from any functions in the scanf family against the number of items whose value you want to set. That will tell you whether or not you've read everything you expected. Also, bear in mind that it can be tricky to set up the format string properly. I can't think of any examples of nonobvious behavior off the top of my head, but I find I use a lot character sets when I use scanf.
You can find many more of these here...
pb Reply or e-mail; don't vaguely moderate.
The compiler may be able to do it; you can not, as it involves dereferencing a null pointer, which makes it undefined according to the C Standard.
You should use the offsetof macro that the Standard supplies, which your compiler may or may not define as (similar to) the construct you're attempting to use.
You'd use
offsetof( struct _x, b )
add apply it to an instance of struct _x as:
#include <stddef.h>
void doit( struct _x* ix ) {
int i = offsetof( struct _x, b )
int b = *(int*)( ( (char*)ix ) + i ) ;
int* bp = (int*)( ( (char*)ix ) + i )
}
Opinions on the Twiddler2 hand-held keyboard?
Argh! No it isn't! If C++ were a superset, all valid C programs would be valid C++ programs. This is obvious tripe.
Presumably, this doesn't compile with your C++ compiler.
"Who modded him informative? Of course it won't work because he uses C++ keywords as variable names!" Err, that was the whole point. It's a valid C program but not a valid C++ program, therefore C++ isn't a superset of C.
And processing of large data volumes in a fairly straight forward manner is also very good to do in straight and "simple" code. And C is really good for that. (I'm think eg cryto code, which is both quite math intensive and highly sequential.)
I won't comment on your views on OOP, while I don't agree with them I don't think anything good will come out of the discussion. (The general idea with all higher level languages is however to map the language as closely as possible to the algorithms as possible. It becomes obvious when you compare eg sorting algorithms in different languages.)
Now this is just plain wrong. Perhaps you work mainly will micro-controllers but the types of CPUs that are in a typical PC today are not this easy to use at a low level.
First off,
Second, a typical PC today doesn't even execute x86 asm. It's translated internally to it's own micro code (typically more towards RISC) and executes that. Furthermore it is super-scalar and as such executes several instructions at once. It also moves code around and a bunch of things that will make your brain go numb if you start trying to optimize it by hand. Hell, you can't even access all the registers manually in many cases.
And that's just looking at the instructions. If you start taking the memory hierarchy into consideration then you'll soon find yourself in a world of confusion.
Fortunately compilers don't get confused by this. So the way I see it a big importance in the future will be not only how well a language maps to hardware and how it maps to the "algorithms". Of even bigger importance could be how clear things are to the compilers so they can do a proper job. (And in many cases C is very suitable for this today.)
Wow, no down-mods as a troll for you yet?
Well, let's pretend you didn't mean to start a "better language" war, and address your points.
Don't even get me started on the 'C is faster than C++ myth'. Only in the hands of an idiot.
MYTH??? Bring it on, Java-boy. Pick any CPU intensive task, and my C code will DESTROY your best Java code for speed.
Java does have its uses, including decent type checking and memory management, as you mentioned. Those carry a cost, however. You don't get something for nothing, and with Java, the cost comes in the form of a performance hit.
most programmers don't have enough training to use a more complex language.
A curious statement... Would you care to give a few examples of more "complex" languages? Particularly with regards to their greater-than-Turing-completeness compared to C?
Or do you mean syntactically, in the sense that you find Brainfuck and Malbolge the epitome of a perfect programming language?
C is really just glorified assembly language.
Yes and no. For the most part, you can trivially convert C to assembler line-by-line, without too much effort. However, the nice neat flow control mechanisms of C makes it almost immeasurably easier to work with than assembler. Don't get me wrong, I do like asm (just can't beat it for speed), but it works best for drop-in function replacements, not for creating the entire framework of a large application.
I think C is only still alive because it is supported on most systems,
Heh... Which, ironically enough, counts as the ONLY reason Java came into existance, and even now that it has "matured", I can build an ANSI-C compatible program on about 6x more platforms than you can run a standard Java app on (whichver "standard" of compatibility you want to pretend exists for Java).
Now go ahead, suck up the humility and grudgingly point out that, since most Java implementations come written in C, you could build a VM on any machine with a C compiler. But that kinda defeats your own point. (And, at least half of those platforms lack the resources to actually *use* the Java VM, although I have to admit I'd like to see someone try using Java on an embedded 68HC05 with 4k ROM and 256 bytes of RAM, if just for the amusement value).
Java has its place. C has its place. Scheme has its place. Perl and Python have their place. Tcl/Tk have their place. I won't pretend people can (or rather, "should", since technically anything the machine can do, you can use C to make it do so) use C for everything, if you don't pretend that C hasn't made it as the single most widely supported and generally hardware-wise powerful language for a reason - Namely, it works, and what it does, it does well. You can try to use a hacksaw to cut lumber, but don't blame the hacksaw for doing the job poorly.
I agree with you, but you have invoked a pet peeve of mine.
[pedantic]
They are braces, not "curly brackets", let alone "brackets".
These things have perfectly good names.
() parentheses
[] brackets
{} braces
[/pedantic]
Jeeze, there's nothing like taking a bunch of idosyncratic preferences and treating them as best practice, let alone enforcing them at a workplace.
I note that Pike doesn't even come close to labeling his piece "Best Practice For C Coding" - for which I thank him.
He does have points that are at least arguably valid, but he lost me at the end.
"Include files should never include files" ?! Pure bull-freaking-crap hogwash. Rather the opposite is the case! Every include file should include every dependency include file. And order dependency of include files is a no-no. It is quite easy to eliminate all order dependencies, and if I have a religious rule, this is it.