Languages/C/tips

From UIT
Revision as of 06:18, 12 July 2012 by Zas (Talk | contribs)
Jump to: navigation, search

Contents

C tips, tricks and... traps

After ten years of C programming, let me gather some piece of code I saw...

Tip : Write readable code

  • First, write and test code that works can be easily understood.
  • If it has no efficiency (CPU or memory) problems, let it.

Tip : dummy read of a register

Some register peripherals, especially on embedded systems must be read to be cleared. Here is a nice way of doing it.

/* Suppose this is the address of a memory mapped status register */
volatile uint32_t *some_status_register;
 
 
/**
 * Now suppose that we want to clear it, so here is a way
 */ 
void read_and_discard_status_reg(void)
{
    uint32_t dummy;
 
    dummy = *some_status_register;
}
 
/**
 * And here is another way, cleaner
 */ 
void read_and_discard_status_reg(void)
{
    /* the void cast will do the read, sure ;) */
    (void)*some_status_register;
}

Trap : if (a = b)

Remember, '=' is different from '=='. Any decent compiler used with decent options will warn you.

int a = 12;
int b = 13;
 
if (a = b)
{
   printf("12 = 13 ?!?");
}

Tip : if (result = function_call()) warning

Your compiler warn you if you test the return value in the if ? add one stage of braces around and it's gone

/* This should do a warning */
if (a = strlen("toto)")
{
 
}
 
/* This will not warn */
if ((a = strlen("toto"))
{
 
}

Trap : sizeof('a')

Here is a bad joke, what is sizeof('a') ?

#include <stdio.h>
 
int main(int argc, char *argv[])
{
        return printf("sizeof('a') = %ld\n", sizeof('a'));
}

And the result is... 4, or at least sizeof(int) which depends on your compiler!



Tip : signed or unsigned char ?!?

gcc char type is neither signed nor unsigned. In the following code, gcc will only compile the test_char function without warning. Solution : cast your unsigned char* to a char* ((char*)msg)

#include <stdint.h>
#include <string.h>
 
int test_unsigned_char(const unsigned char *msg)
{
        return strlen(msg);
}
 
int test_signed_char(const signed char *msg)
{
        return strlen(msg);
}
 
int test_char(const char *msg)
{
        return strlen(msg);
}
Personal tools
Namespaces
Variants
Actions
Navigation
Browse
Toolbox