lipska the kat <> writes:
> On 04/10/12 09:30, Keith Thompson wrote:
>> lipska the kat<> writes:
>> [...]
>
> [snip]
>
>> C, as the saying goes, gives you enough rope to shoot yourself in the
>> foot. I'll show you a concrete example:
>
> [snip]
>
> gcc example.c
> example.c: In function ‘write_array’:
> example.c:4:9: error: ‘for’ loop initial declarations are only allowed
> in C99 mode
> example.c:4:9: note: use option -std=c99 or -std=gnu99 to compile your code
> example.c: In function ‘read_array’:
> example.c:10:9: error: ‘for’ loop initial declarations are only allowed
> in C99 mode
> make: *** [example] Error 1
>
> gcc -ansi example.c
> ditto above
Right, I used a C99-specific feature, and gcc with no arguments, or with
"-ansi", doesn't implement C99. You can avoid that by using "-std=c99",
or by changing
for (int i = 0; i <= 5; i ++) {
/* ... */
}
to:
int i;
for (int i = 0; i <= 5; i ++) {
/* ... */
}
Note that the "int i;" declaration has to be at the top of the block,
before any statements (a C90 restriction that C99 removed).
> gcc -std=c99 -Wall example.c
> example.c: In function ‘main’:
> example.c:19:13: warning: unused variable ‘z’ [-Wunused-variable]
> example.c:17:13: warning: unused variable ‘x’ [-Wunused-variable]
>
> gcc -std=c99 -O1 -Wall example.c
> ditto above
>
> gcc -std=c99 -O2 -Wall example.c
> example.c: In function ‘main’:
> example.c:19:13: warning: unused variable ‘z’ [-Wunused-variable]
> example.c:17:13: warning: unused variable ‘x’ [-Wunused-variable]
> example.c:5:20: warning: array subscript is above array bounds
> [-Warray-bounds]
>
> gcc -std=c99 -O3 -Wall example.c
> example.c: In function ‘main’:
> example.c:19:13: warning: unused variable ‘z’ [-Wunused-variable]
> example.c:17:13: warning: unused variable ‘x’ [-Wunused-variable]
> example.c:5:20: warning: array subscript is above array bounds
> [-Warray-bounds]
> example.c:11:19: warning: array subscript is above array bounds
> [-Warray-bounds]
Yes, all those warnings are valid. An "unused variable" warning
doesn't mean that your program is wrong, it just means that you've
probably made a logical error.
The "array subscript is above array bounds" is more serious. As I
said, I deliberately wrote a program whose behavior is undefined;
this absolutely was *not* an example of what you should do.
The program attempts to store values outside the bounds of an array.
I added extra array declarations to try to give those accesses
somewhere to go.
> 0 1 2 3 4 5 every time
>
> Now I'm really confused
The program's behavior is undefined. Printing 0 1 2 3 4 5 every
time is therefore perfectly valid, since nothing in the standard
says it *shouldn't* behave that way.
If you go beyond what the standard actually says, there are reasons
why it behaves the way it does. The arrays x, y, and z probably
happen to be stored next to each other in memory. Writing past
the end of y probably clobbers the beginning of either x or z.
Since x, y, and z are all in memory that you "own", the program is
able to do that with no apparent problem.
A more stringent compiler might have caused the program to crash
when it tried to store past the end of y. Most compilers don't
do that because it requires explicit checking, which is expensive
(it would catch incorrect programs, but slow down correct programs).
A cynic might say that C compilers are designed to let you get your
wrong answers as quickly as possible.
> Maybe I should be reading the C99 spec %-}
It's not easy reading, and there's not really anything in it that
explains the way this program behaves. As far as the standard is
concerned, running that program could make demons fly out of your
nose (obviously that won't really happen, but nothing in the C
standard forbids it).
It's entirely possible that my example was more complex than it
should have been. If you don't understand it, don't worry about it
too much for now. Perhaps you should concentrate more on writing
correct code than on understanding incorrect code.
--
Keith Thompson (The_Other_Keith)
kst- <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"