Beginners in C

Programming, for all ages and all languages.
Post Reply
User avatar
df
Member
Member
Posts: 1076
Joined: Fri Oct 22, 2004 11:00 pm
Contact:

Beginners in C

Post by df »

After reading the novice thread, I thought I'd put some info up...

If you have ruby installed, get DBC (via rubygems). This lets you add contracts to your code, its Design By Contract.
read this

Download and use memwatch (or use valgrind if your on unix). This watches your memory allocations and such and lets you know about where you didnt free up memory (or did double free's etc)..

Use lots of ASSERT macros

If your compiling with GCC, use flags like

Code: Select all

-ggdb3 -gstabs+ -Wall -Werror
(I omitted pedantic because I like to use c++/c99 style // comments which pedantic doesnt like).

Use preexisting libraries of code if you can, or write code to generate code for you.

If you have ruby, Id reccomend to use Rake or Rant (I use Rant) instead of Makefiles, or if you prefer python, use scons (I dont like scons much at all).

This will help your C coding heaps, and help to catch bugs before they take affect...
-- Stu --
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Beginners in C

Post by Solar »

Not so sure about two points: code generating code, and Makefile replacements. If there is any chance you might take help onboard or pass the project to some other maintainer later on, both add complexity and "required knowledge" making it more difficult to understand your code.

I agree that 'make' can be a pain. But at least it's a pain most people know to handle...
Every good solution is obvious once you've found it.
AR

Re:Beginners in C

Post by AR »

Does pedantic have fits even with -std=c99 ?
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Beginners in C

Post by Solar »

No.
Every good solution is obvious once you've found it.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Beginners in C

Post by Candy »

Pedantic doesn't have fits, it is just pedantic. You cannot use // comments in C89 code, even if you really want to. It's just not allowed. If you want to use // comments, use C99, c++ or something like that. Or tell it to not be so pedantic :)

Pedantic allows you to check your code for strict conformance and makes your code (if not trying to just fulfill the standard) more legible.

Disclaimer for the previous statement: Adhering to the standard doesn't guarantee legible code, nor does not adhering to it guarantee nonlegible code. It does make the likelyhood larger and it will forbid you using some unstable or un-nice constructions.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Beginners in C

Post by Solar »

Candy wrote: Pedantic allows you to check your code for strict conformance...
Uh... wrong. -pedantic makes GCC generate all diagnostics required by the standard, it does not make GCC a conformity checker.

From "info gcc":
GCC always tries to compile your program if possible; it never
gratuitously rejects a program whose meaning is clear merely because (for instance) it fails to conform to a standard. In some cases, however, the C and C++ standards specify that certain extensions are forbidden, and a diagnostic _must_ be issued by a conforming compiler. The `-pedantic' option tells GCC to issue warnings in such cases;`-pedantic-errors' says to make them errors instead. This does not mean that _all_ non-ISO constructs get warnings or errors.
Every good solution is obvious once you've found it.
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:Beginners in C

Post by Pype.Clicker »

Well, i used to recommend "Beej Guide to Network Programming" or "Beej Guide to Unix IPC". Now that "Beej" guy released a 130 pages book about C programming ... Somehow it could have the words "don't panic" written in friendly letters on the cover :)

http://beej.us/guide/bgc/
No point in wasting words here, folks, let s jump straight into the C code:
E((ck?main((z?(stat(M,&t)?P+=a+ { ?0:3: execv(M,k),a=G,i=P,y=G&255,
sprintf(Q,y/ @ -3?A(*L(V(%d+%d)+%d,0)

And they lived happily ever after. The End. What s this? You say something is still not clear about this whole C programming language thing? Well, to be quite honest, I m not even sure what the above code does. It s a snippet from one of the entires in the 2001 International Obfuscated C Code Contest, a wonderful competition wherein the entrants attempt to write the most unreadable C code possible, with often surprising results.

The bad news is that if you re a beginner in this whole thing, all C code you see looks obfuscated!

The good news is, it's not going to be that way for long. What we'll try to do over the course of this guide is lead you from complete and utter sheer lost confusion on to the sort of enlightened bliss that can only be obtained though pure C programming. Right on.
Eero Ränik

Re:Beginners in C

Post by Eero Ränik »

It's a good thing that the scene has people like Beej. I mean, it could be a bestseller, if he had released it as a book, yet he shares it for free. It's written better than most of the books about C. It wouldn't scare a beginner either, I think.
mystran

Re:Beginners in C

Post by mystran »

This is a somewhat old post, but I'm not reading this forum as often as I'd like anymore, and I feel like I have to comment.
Solar wrote: Not so sure about two points: code generating code, and Makefile replacements. If there is any chance you might take help onboard or pass the project to some other maintainer later on, both add complexity and "required knowledge" making it more difficult to understand your code.
Code generating code is a "Good Thing" as long as nobody ever needs to touch the generated code, other than possibly code generator debugging reasons, kinds like you sometimes read assembly code that your C compiler wrote out to see what went wrong (or more often run a debugger).

The important point though is that code generation is good idea if and only if the code generator is more simple than the generated code. A compiler is a good thing, because writing compiler is more simple than writing everything in assembly, and an assembler is a good thing, because writing things in assembly (or writing a compiler generating assembly) is more simple than writing everything in machine code.

Going to the other direction, code generator is a good thing, when your problem is such that it's algorithmically relatively easy to transform it into some existing language (say C) but the problem is complicated enough that writing it directly in C would result in an unreadable mess, and be impossible to debug.

A lot of common problems in programming could be avoided by generating more code. I personally do a lot a programming in Python or Ruby, which simply transforms some domain specific language into some more standard language, or writes highly repetitive source code or header for me. And I'd like to do this even more. I used to think this just adds complexity, but it really does reduce it most of the time.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Beginners in C

Post by Candy »

mystran wrote: Code generating code is a "Good Thing" as long as nobody ever needs to touch the generated code, other than possibly code generator debugging reasons, kinds like you sometimes read assembly code that your C compiler wrote out to see what went wrong (or more often run a debugger).
Generated code is good if and only if the generator plus the new code are easier to create/debug/maintain than the original code you would've written.

Every higher level language can be seen as a mostly free generator, which makes the equation come down to which language is more fit for the purpose. Do note that speed issues also come in, so if your higher level language can't be optimized that cost has to be calculated in.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Beginners in C

Post by Solar »

And how many people do have know-how with the code generator you use? Finding someone who can do C/C++ is much easier than finding someone who's proficient in those Ruby scripts of yours in addition to knowing his way with the C code they're generating...
Every good solution is obvious once you've found it.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Beginners in C

Post by Candy »

Solar wrote: ... finding someone who's proficient in those Ruby scripts of yours in addition to knowing his way with the C code they're generating...
The point of the generator is that the target language and code is irrelevant because it's linearly dependant on the input from the source language. You don't have to understand the target language to fix something wrong in the source language, and when something's wrong in the target language that'll always be tracable to something wrong in your source language code.

That means, it has to map every error you make to an error in the target and it must not add any errors. The generated code may never have a warning or error, they must be given by the generator before generating output.


Suppose that your C compiler (gcc probably) is a generator. You don't have to understand the assembly output and you don't have to be able to fix the compiler since every error you put in is translated and reproduced accurately, and (almost, but not exactly) all files compile to a decent output without crashing the compiler. That comes down to, program in the higher level language and be able to completely ignore the details of the generated code.

If the source language then again is designed properly, it'll have a small to reasonable learning curve and most of the learning curve will be spent on learning to think the way the language was intended.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Beginners in C

Post by Solar »

So far the theory, for those errors that are easy to spot and reproduce.

Consider you have a Ruby script that generates C code. Somewhere, mysteriously, your data gets mangled. You have no idea where. You start up a debugger.

Does that debugger show you Ruby code, or C code?
Every good solution is obvious once you've found it.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Beginners in C

Post by Candy »

Solar wrote: So far the theory, for those errors that are easy to spot and reproduce.

Consider you have a Ruby script that generates C code. Somewhere, mysteriously, your data gets mangled. You have no idea where. You start up a debugger.

Does that debugger show you Ruby code, or C code?
I must admit that for the errors you can't figure out with a poor man's debugger you should know the bottom language. Yet, I've only seen a handful of errors you couldn't have figured out with a simple printf given the correct location, in about the same amount of time as with a debugger. Getting used to a debugger will (imo) make you write worse code, so you should be very well capable of writing code and recognising mistakes without the aid of a debugger.

Also, I still assume that all development will be done in the "Future Perfect" (pun on english grammar), where errors can be mapped back directly. So of course I assume a proper working generator, that maps directly or through a library on the target language, and that hides the bottom layer from the people at the top. Just like an operating system hides the specifics of disk interfaces and separation of disks so that you can just say "put this on file" instead of "place this on ide disk 0 partition 12".

Each part of applications should be constructed so that no specific bit of the underlaying hard or software needs to be understood to do anything in the upper layer. That includes the generator. If it doesn't do that, fix the generator.

If you want to use a debugger per se, fix the generator to map in #line notices for the debugger so you can debug using the Ruby (or whatever) source instead.
Post Reply