Tips

From C

Jump to: navigation, search

Contents

Tips

This page is semantic advice, not whitespace formatting, indendation, or other similar issues.

Don't cast malloc()

(Or indeed any function returning void *) Two reasons why:

  • It's unneccessary. malloc() returns void *, and a void * value does not need casting when being stored in a pointer.
  • It's dangerous. Functions default to returning int if they have no prototype. So, if you forget to include the header, there is no prototype, and malloc is assumed to return int. The cast explicitly tells the compiler to ignore this, and that you know what your doing - in other words, it hides your error from you.

See Casting for more along the same lines.

malloc.h is obsolete

It dosen't exist any more. malloc() has been defined in stdlib.h since ANSI.


Don't "get rid of the compiler warning"

Most people I've seen with this attitude are essentially typing random things just to make the compiler's error messages or warnings go away. Don't do that.

Warnings are there to warn you to examine your code, and check you're doing what you actually intended to do: heed them. Do not blindly "get rid" of them.

A common example is a compiler warning about attempting to dereference a type as if it were a pointer; the hapless programmer simply casts it, and the message goes away. Everything looks fine, until the program is run, and crashes for no apparent reason.

Write useful comments

Don't explain what your code is doing - the code should be clear enough to do that itself. The worst-case example is:

   i++; /* increment i */

Instead, explain why your code is doing what it's doing.

Check the return status of functions you call

Especially syscalls. Many people seem to totally ignore the "RETURN VALUES" section of the manpages.

What happens if, for example, malloc() fails to allocate memory?

Have your code flow through the most common case

Handle abnormalities as exceptional cases, with conditionals. Leave the "default" flow of code for the "main" condition:

   int a, b;
   
   a = step1();
   if(!a)
       exit(1);
   
   b = step2();
   if(!b)
       exit(2);
   
   c = step3();
   if(!c)
       exit(3);
   
   makeuseof(a, b, c);

Duff Elses

Tom Duff (of Duff's Device fame) has a nice article on Deep Nesting. This explains how to remove vast amounts of intending in conditional statements by returning as early as possible from functions.


Return as early as possible

Return from a function as soon as you have an answer. It's ok to have multiple returns (unlike in, say, Fortran). Do not have a "returnme" variable.


Don't switch on int

Where possible, switch on enums, instead--the compiler can be able to warn you about unhandled values for which you're missing a case.

Personal tools