C
Memory
Some Comment From slashdot.org
In x86 (assumed from here on) assembly, there are some 'quick' operations to
read, write, and test memory (LODS*, STOS*, SCAS* respectively - there are
probably more). The CPU has registers, or variables that are counters, or
hold the memory addresses in question - in these cases a source memory
position and a destination memory position. When you performs these commands
the memory registers either increment or decrement value (position)
depending on how the direction flag is set. GCC is assuming the flag is
clear and the pointers will increment - go forward after each call. If the
direction flag is set incorrectly upon calling these string or memory
functions, the pointers could go backwards and thus copy (or scan) the wrong
chunk of memory to the wrong destination.
Say our source memory contains:
Address: 0123456789ABCDEFGHIJKLMNOPQRSTUV
Contents: XXXXXXXXA car is heavy.-XXXXXXXX
Let's pretend the hyphen is a null (the string terminator or "stop" in most
languages and OS) If I want to perform a strlen on that string at position
'8', it should return 15 characters because it found the null at 'N' If the
direction flag is wrong, it will not scan 8, 9, A, ... but 8, 7, 6, ...
until it finally finds that null or crashes with an access violation.
And with memory, I want to copy 5 bytes from '8' to position 'P' If that
works correctly, we get this in memory:
Address: 0123456789ABCDEFGHIJKLMNOPQRSTUV
Contents: XXX-!@#$A car is heavy.-XA carXX
However, if the direction is wrong, we will get:
Address: 0123456789ABCDEFGHIJKLMNOPQRSTUV
Contents: XXX-!@#$A car is heav!@#$AXXXXXX
See how '8' copied to 'P' as expected, but decrementing we then get '7' to
'O', etc
We now have corrupt memory. If we so a strlen, strcat or other
null-expecting function on that string located at '8' we will see garbage
where the memory copy wrote the wrong data to the wrong position. For the
nitpicks, this example used per-byte, there are 16, 32, 64 bit variants of
the functions that would cause similar problems bit in 2, 4, 8 byte chunks.
GCC
Advice on Compiling (comment from slashdot.org)
Build your code with -Wall -Werror (or your compiler's equivalent). Once
you clean up all the crud, that pops up, crank it up with -W
-Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes
-Wpointer-arith. Once there — add -Wreturn-type -Wcast-qual -Wswitch
-Wshadow -Wcast-align and tighten up by removing the no in
-Wno-unused-parameter. The -Wwrite-strings is essential, if you wish
your code to be compiled with a C++ compiler some day (hint: the correct
type for static strings is " const char *").
For truly clean code, add -Wchar-subscripts -Winline -Wnested-externs
-Wredundant-decls.
The people, who wrote and maintain the compiler, are, most likely,
several levels above you in understanding programming in general and
C-programming in particular. Ignoring the advice their code generates is
foolish on your part...
As a minimum, solved warnings will make your code more readable by
reducing/eliminating the "Why is he doing this?" questions. More often
than not, they point out bugs you would otherwise spend hours chasing
with a debugger later.
And they make your code more portable. But if you don't understand, why
a warning is generated - ask around. Don't just "shut it up". For
example, initializing a variable at declaration is usually a no-no. If
the compiler thinks, the variable may be used before being initialized,
scrutinize your program's flow. If you can't figure out, it may some
times be better to disable this one warning temporarily with
-Wno-uninitialized to move on, instead of shutting it up for ever by a
bogus "= 0" or some such...
The book may well say something about respecting warnings, but the
review does not, which is a shame.