jacob said:
Erwin Lindemann wrote: [...]
Consider the following test program
/* begin foo.c */
#include <stdio.h>
#include <string.h>
void test(int n, size_t size)
{
int i;
for(i = 0; i < n; i++) {
unsigned char vla[size]; //<<<<<<<<<<<<<<<<<
memset(vla, (i & 255), size);
printf("step %d: vla=%p\n", i, &vla[0]);
}
}
int main(void)
{
test(10, 256*1024L);
return 0;
}
/* end foo.c */
With gcc, 'vla' is reused in every iteration, i.e., the address
of 'vla[0]' is identical in every step.
If I change the marked line above to
unsigned char vla[size*i+1];
and change the size expression in the memset call to
the same expression, gcc will produce the following
output in my linux box:
step 0: vla=0xbffff990
step 1: vla=0xbffbf990
step 2: vla=0xbff7f990
step 3: vla=0xbff3f990
step 4: vla=0xbfeff990
step 5: vla=0xbfebf990
step 6: vla=0xbfe7f990
step 7: vla=0xbfe3f990
step 8: vla=0xbfdff990
step 9: vla=0xbfdbf990
As you can see, the addresses are different each time.
If the size is different in each step, that is not surprising.
Have you tried printing the address of vla's last element, too?
gcc is doing simply a constant propagation. It notices that the
expression in the VLA size is a constant expression within the
affected block, and optimizes the case you presented above
to reuse always the same block.
I'm not convinced this is what happens. I think gcc is reusing
the space reserved for 'vla' each time its scope is left and
re-entered, in the same way it does so for fixed size arrays
and scalar object types.
Fine, maybe I could do such an optimization too, so that the
clique of comp.lang.c (where you belong)
I do? Usenet is a strange place.
can have a harder time, but what for? This optimization
would only optimize a special case.
It would also allow programs to work correctly that define
variable length array inside a loop body.
I will do it some day when I introduce strength reduction into
loop bodies. But I am skeptical of those classic optimizations.
I am at 80-90% of the speed of gcc in many benchmarks, but the
compilation speed of lcc-win is 600-800% better than gcc. I
prefer this situation.
Which situation? The optimization you are talking about or the
memory leakage I discovered?
However, with lcc-win32, output is as follows...
step 0: vla=0x002ffea0
step 1: vla=0x002bfea0
step 2: vla=0x0027fea0
step 3: vla=0x0023fea0
[*CRASH*]
, meaning, new storage is allocated for 'vla' at every iteration,
eventually exhausting all available auto storage.
Now, is this just implementation dependant and this kind of construct
should be avoided, or is one of these compilers not working correctly?
Should a bug report be filed?
You can only file a bug report if you buy maintenance at premium rates.
Well, you already know about the problem now, and expressed you are not
going to do anything about it. How would buying "maintenance at premium
rates" help in this situation?
I have a special price for clique members sorry!
You are welcome.
Thanks