View also related posts:

 

 14   Difference between '' and ""

 the ' and “ are very different:

Suppose you have

char str[100];

char *str_ptr;

     str_ptr = str;

then str_ptr and str would both point to the first element in the array. Suppose you wanted to initialise this string by making the first element a zero byte. You could do

     strcpy(str_ptr, "") /* or strcpy(str_ptr, "") */

or

     *str_ptr = '';

but

     str_ptr = "";

would do something quite different. It would create a string in your executable (namely "") and set str_ptr to point to it with potentially disastrous effects.



 15  Optimization

Turning on optimisation may change the behaviour of your program, especially if the program isn't perfect. For instance, if optimisation re-positions a variable into a register it's less likely to be 0 initially, so if you've not initialised variables before use you might get a surprize.


 16  Mismatched header files

Suppose foo.h contains:

        struct foo { BOOL a};

file F1.c  contains

        #define BOOL char

        #include "foo.h"

file F2.c contains 

        #define BOOL int

        #include "foo.h"

now, F1. and F2 disagree about the fundamental attributes of structure "foo". If they talk to each other, You Lose! 


 17  Unpredictable struct construction

Consider this bit packing struct:

    struct eeh_type

    {

            uint16 size:          10;   /* 10 bits */

            uint16 code:           6;   /* 6 bits */

    };

Depending on which C compiler, and which "endian" flavor of machine you are on, this might actually be implemented as

        <10-bits><6-bits>

or as

        <6-bits><10-bits>


Also, again depending on the C compiler, machine architecture, and various mysterious preference settings,

the items might be aligned to the nearest 8, 16, 32, or 64 bits.


So what matters? If you are trying to match bits with a real world file,

everything!


Need another way to lose big?  How about this:

Rect foo = {0,1,2,3}; // assign numbers to the first four slots


You may think you know what those four slots are, but there's at least an

even chance you'll have to discover the hard way if the structure ever

changes.

18 Utterly unsafe arrays 

This is so obvious it didn't even make the list for the first 5 years, but C's arrays and associated memory management are completely, utterly unsafe, and even obvious cases of error are not detected.


 int thisIsNuts[4]; int i; 

  for ( i = 0; i < 10; ++i ) 

  { 

    thisIsNuts[ i ] = 0;     /* Isn't it great ?  I can use elements 1-10 of a 4 element array, and no one cares */ 

  }


Of course, there are infinitely many ways to do things like this in C. 

 

 19  Octal numbers

In C, numbers beginning with a zero are evaluated in base 8.  If there are no 8's or 9's in the numbers, then there will be no complaints from the compiler, only screams from the programmer when he finally discovers the nature of the problem.  

 int numbers[] = { 001,// line up numbers for typographical clarity, lose big time 

                   010,        // 8 not 10 

                   014 };     // 12, not 14 

Not convinced ? Try atoi("000010");


20  64 Bit Madness 

With the advent of 64 bit architectures, there are many new ways that C will screw you, especially in the "rare" case that array indeces approach or exceed 2^31.  The basic problem is that signed and unsigned 32 bit integers are accidents waiting to happen when used to index into large arrays.   These bugs are mostly theoretical, since most arrays will remain reasonably sized.  But expect a whole new universe of catastrophic failures of trusted and thoroughly debugged systems when they are stressed with large arrays.   Viva64 has a product to sell, but it looks like a good one.

 

I took these mistakes from here http://www-h.eng.cam.ac.uk/help/tpl/languages/C/teaching_C/node34.html

 

Gg1