C pitfalls
-
Dangling pointer:
-
char* foo( void )
{
char str[100];
[..]
return str; /* WRONG, points within call stack, probable crash */
}
-
A number beginning with 0 (zero) is interpreted as octal, not decimal.
-
int limit = 0100; /* oops, limit is assigned 64 (decimal) */
-
sizeof() means how many bytes (not elements) and includes trailing null byte of a string.
-
-
Literal strings might be compiled into a read-only segment.
-
One case where this pitfall manifests is by passing a literal string
as a parameter to a function that tries to modify string.
-
Equality operators have precedence over bit operators (when in doubt, use parentheses).
-
IIRC, Dennis Ritchie said this was a mistake in design of C.
if ( x & MASK == VALUE ) /* WRONG: equivalent to (x & (MASK==VALUE)) */
if ( (x & MASK) == VALUE ) /* right */
-
char is signed, and will be promoted to a signed integer (not unsigned).
-
-
Bit-field structs aren't portable.
-
-
Body of a macro and every parameter should be parenthesized to prevent precedence bugs:
-
#define MAX(a,b) a > b ? a : b /* WRONG */
/* WRONG: result=1 (0xffff vs. y because '>' has more precedence than '&') */
x = 1; y = 2; result = MAX(x & 0xffff, y);
-
goto pitfall:
-
An example of a bug caused by goto. When
match is false,
intent is to break the inner loop, and continue outer loop.
for ( i = 0; i < MAX; ++i )
{
no_match:
for ( j = 0; j < MAX; ++j )
{
if ( ! match )
goto no_match;
}
}
Above code is incorrect. goto skips incrementing i
and causes outer loop to become stuck!
A correction is to jump to bottom of outer loop:
for ( i = 0; i < MAX; ++i )
{
for ( j = 0; j < MAX; ++j )
{
if ( ! match )
goto no_match;
}
no_match:
}
|