Variable length arrays

  • Thread starter Erwin Lindemann
  • Start date
J

jacob navia

Joachim said:
Even if it's not required by a standard, this is a Quality Of Implemenation
issue.
Destroying those arrays would surely not violate the standard, would it?
And I'd find such a "feature" much more usefull than a printf format
specified for complex numbers...

Allocating a variable length array within a loop?
Look, I work for the regulars here, fixing things that are not broken
like this same person that insisted on calling a function
"abs" and complaining that stdlib.h defines "abs" and that he
receives an error message


The same guy that starts now this thread.

Yes, he can now BUY a maintenance contract and I
will do it after I receive his money ok?

The same people try to destroy lcc-win saying that is
commercial and that I am just here for the money I do.

OK

Then PAY!
 
J

Joachim Schmitz

Micah said:
In addition to the standard, the relevant text of which has been
quoted numerous times on this thread.
I found it only once, by you. And I'm not enough of a language lawyer to
determine whether that realy requires what you claim it does.
Jack Klein called it a QOI issue (and AFAIR he is a language lawyer), and I
agree that it is _at least_ that, a QOI issue.

Bye, Jojo
 
M

Micah Cowan

Joachim Schmitz said:
OK, see how unclear your wording was?

Not unclear, just irrelevant. That he doesn't make some optimization is
no bug. The bug is that he leaks memory.

You obviously haven't been reading. *Sigh* here it is again, (in a
previous version I even clarified some wording based on context, I
won't bother here since it's doubtful you'll read it this time
either):

6.2.4#6:
For such an object that does have a variable length array type, its
lifetime extends from the declaration of the object until execution of
the program leaves the scope of the declaration.

That scope is exited and re-entered upon every iteration (a compound
statement being just the single statement that is run by for).
And what does common sense say? Isn't it you how constantly wants to improve
the standard?

Agreed. Even if the standard "allowed" your behavior, it's clearly
brain-dead to leak memory wherever you feel like it.
 
W

Willem

jacob wrote:
) 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

Note that the difference between the addresses is the same each time, and
happens to be equal to 'size'. It is very probable that the *end* address
of the allocated block is the same each time. The stack probably grows
downward on this implementation.

The point is that the allocated blocks *overlap*.

) gcc is doing simply a constant propagation. It notices that the

No, gcc is destroying and reusing each block after its lifetime ends.
If the bock happens to be the same size, it happens to end up at the
same place by coincidence.

) expression in the VLA size is a constant expression within the
) affected block, and optimizes the case you presented above

No optimization is needed for this special case.

) to reuse always the same block. Fine, maybe I could do such an
) optimization too, so that the clique of comp.lang.c (where you
) belong) can have a harder time, but what for? This optimization
) would only optimize a special case.

As shown above, this is false. It works for *all* cases.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
J

Jean-Marc Bourguet

jacob navia said:
because there is no bug./

Nowhere in the standard it is written that I must free those
arrays

IMHO, this point of view is as formalist as some about which you often
complain (again IMHO, sometimes rightfully, sometimes wrongly, but that's
another story).

Yours,
 
J

Joachim Schmitz

jacob said:
Allocating a variable length array within a loop?
Look, I work for the regulars here, fixing things that are not broken
No, you're neither. Actualy you refuse to do either. I'm not claiming this
to be wrong, just stating facts.
like this same person that insisted on calling a function
"abs" and complaining that stdlib.h defines "abs" and that he
receives an error message
So you judge about whether a bug report reports a real bug by looking at who
reports it?
C'mon, grow up.
The same guy that starts now this thread.

Yes, he can now BUY a maintenance contract and I
will do it after I receive his money ok?
OK, your decision. At the same time others get a mostly useless complex
number format for free. One that the comitee expicitly called useless and
not just forgot, as you claimed.
I don't understand that.
The same people try to destroy lcc-win saying that is
commercial and that I am just here for the money I do.

OK

Then PAY!
No, I certainly won't. For one because I don't need a C-compiler for
Windows, but also because I don't like your attitude when it comes to
legitimate bug reports.

Your're frequently attacked here for advertising your compiler, but miss the
best advertisement you can get: sensibel replies to bug reports and prompt
fixes and generally a more moderate discussion style.

Bye, Jojo
 
J

Jack Klein

jacob navia said:
Erwin said:
If a VLA appears within a loop body, it seems the behavior is
different with two different compilers I tried. I looked at the
standard text, but couldn't find a definite answer there either.

There is no definite answer. It is implementation dependent.
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.

The standard doesn't say that "vla" must have the same address at
every iteration of the loop, and it shouldn't matter whether it does
or not. In fact, a strictly conforming program can't tell whether the
same memory is re-used, since the address becomes invalid at the end
of the block, when the lifetime of "vla" has ended.

Really? I see nothing that makes the OP's program, which you quoted
in full above, not strictly conforming. And the output of that
program most certainly does generate output that shows the same memory
is reused by one implementation, not by another.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
F

Falcon Kirtaran

Erwin said:
If a VLA appears within a loop body, it seems the behavior is
different with two different compilers I tried. I looked at the
standard text, but couldn't find a definite answer there either.

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.

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?

Thanks

For one, &vla[0] == vla.

The array vla[] should be allocated on the stack, and popped off of it
at the end of the for loop, so indeed if the error is that you have run
out of memory, this is a pretty bad compiler error, I'd say.

It might not be a bad idea to allocate that memory on the heap using
malloc() (or alloca() if your compiler supports it). This way, you will
be able to use its return value to detect this and exit gracefully.
 
M

muntyan

jacob navia said:
Erwin Lindemann wrote:
If a VLA appears within a loop body, it seems the behavior is
different with two different compilers I tried. I looked at the
standard text, but couldn't find a definite answer there either.
There is no definite answer. It is implementation dependent.
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.
The standard doesn't say that "vla" must have the same address at
every iteration of the loop, and it shouldn't matter whether it does
or not. In fact, a strictly conforming program can't tell whether the
same memory is re-used, since the address becomes invalid at the end
of the block, when the lifetime of "vla" has ended.

Really? I see nothing that makes the OP's program, which you quoted
in full above, not strictly conforming.

It prints pointers, in implementation-defined format.
And the output of that
program most certainly does generate output that shows the same memory
is reused by one implementation, not by another.

It shows that implementation prints different hex
strings for those arrays, not that memory is reused
or not reused. *We know* what in that particular
setup those hex strings mean, but it's not something
a strictly conforming program could use to judge about
memory blocks (and that doesn't even make sense
from the standard point of view, a dead object is
not an object). What does show non-conformance is
the crash.

Yevgen
 
M

muntyan

No, you're neither. Actualy you refuse to do either. I'm not claiming this
to be wrong, just stating facts.

What facts? I personally got an impression that Jacob does
fix bugs. I don't have facts though.
So you judge about whether a bug report reports a real bug by looking at who
reports it?
C'mon, grow up.

Jacob did analyze the issue and decided there is
no bug. Wrongly, yes. But he didn't make that
decision because of who posted a "bug report". And
in his defense, most people posted in this thread
actually agreed that it's not a non-conformance bug
(which it is).
OK, your decision. At the same time others get a mostly useless complex
number format for free. One that the comitee expicitly called useless and
not just forgot, as you claimed.
I don't understand that.

If you can't have a kitchen sink in a compiler,
you print complex numbers. What's so hard to
understand about it? It has nothing to do with
JN's reaction to a "bug report" though.
No, I certainly won't. For one because I don't need a C-compiler for
Windows, but also because I don't like your attitude when it comes to
legitimate bug reports.

Yeah, "legitimate bug reports". Legitimate bug report
is when you care, not when all you want is to show
once again in comp.lang.c how much lcc-win32 sucks.
Your're frequently attacked here for advertising your compiler, but miss the
best advertisement you can get: sensibel replies to bug reports and prompt
fixes and generally a more moderate discussion style.

It's amusing how people tell JN about his discussion
style. I recall some even say that JN attacks people!
Funny.

Yevgen
 
K

Kaz Kylheku

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*]

See, this is what happens when the compiler writer becomes infatuated
with alloca. :)
 
K

Kaz Kylheku

I replied with a lengthy explanation that you apparently
did not bother to READ.

The program dies because for a VLA I do not make the

The program dies because you aren't cleaning up the memory when a
block terminates.
optimization that the variable "size" is a loop invariant,
i.e. does not change within the loop.

If you replace
        int tab[size];

with

        int tab[size*i+1];

This tab could still be allocated in the same space. If the stack
grows downward, the starting address will be different. However, I
would expect the end address to be the same. Or very close---alignment
may cause it to jitter slightly.
gcc will ALSO produce different arrays for each iteration.

Oh really?

#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+256*i];
memset(vla, (i & 255), size);
printf("step %d: vla address range == [%p,%p)\n", i,
(void *) vla, (void *) vla + size + 256 * i);
}
}


int main(void)
{
test(10, 256*1024L);
return 0;
}


step 0: vla address range == [0xbffbf990,0xbffff990)
step 1: vla address range == [0xbffbf890,0xbffff990)
step 2: vla address range == [0xbffbf790,0xbffff990)
step 3: vla address range == [0xbffbf690,0xbffff990)
step 4: vla address range == [0xbffbf590,0xbffff990)
step 5: vla address range == [0xbffbf490,0xbffff990)
step 6: vla address range == [0xbffbf390,0xbffff990)
step 7: vla address range == [0xbffbf290,0xbffff990)
step 8: vla address range == [0xbffbf190,0xbffff990)
step 9: vla address range == [0xbffbf090,0xbffff990)

Different starting address, same end. Obviously, someting like alloca
is going on, except that the allocation is tied to the block, not to
the function.
As I explained (and repeat here again) this is an optimization
that I do not do and gcc does.

Bahahahaha. I don't think what gcc is doing is called optimization.
It's called getting the semantics right. That's what gcc is doing (and
not you).
 
K

Kaz Kylheku

Nowhere in the standard it is written that I must free those
arrays

The standard does not specify that those arrays should be destroyed.
They are no longer available, that's all.

Sure, the standard doesn't explicitly say anywhere that the generated
code must not introduce software defects which are not present in the
source code, such as memory leaks. So you're off the hook?

Why not also generate code that randomly freezes? The standard doesn't
specify maximum time which must elapse from the evaluation of one
expression to the next.

Boy, how quick are we to retreat to the standard. Did you know that it
doesn't even say there /is/ such thing as a stack? And here you are,
asking my compiler to clean up something that doesn't even exist!
 
K

Keith Thompson

jacob navia said:
I replied with a lengthy explanation that you apparently
did not bother to READ.

I did.
The program dies because for a VLA I do not make the
optimization that the variable "size" is a loop invariant,
i.e. does not change within the loop.

That optimization, or the lack of it, is not the problem. In cases
where the size of the VLA is *not* a loop invariant, code generated by
gcc will work correctly, and code generated by lcc-win apparently will
blow up.
If you replace
int tab[size];

with

int tab[size*i+1];

gcc will ALSO produce different arrays for each iteration.

It doesn't matter that they're different arrays. What matters is that
only one exists at a time.

Consider this:
for (i = 0; i < 1000; i ++) {
int obj;
}
Would it be reasonable for space to be allocated for 1000 instances of
"obj" simultaneously, before any of them have been deallocated?

Consider this:
for (i = 0; i < 1000; i ++) {
int arr[1000];
}
Would it be reasonable for space to be allocated for 1000 instances of
"arr" simultaneously, before any of them have been deallocated?

Consider this:
for (i = 0; i < 1000; i ++) {
int vla[rand() % 1000];
}
Would it be reasonable for space to be allocated for 1000 instances of
"vla" simultaneously, before any of them have been deallocated?

Why in the world would you answer those three questions differently?

And can you *please* try to respond without sarcasm?
 
J

jacob navia

Kaz said:
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*]

See, this is what happens when the compiler writer becomes infatuated
with alloca. :)

There are two kinds of people in this world.

The people that work, create things, offer them to the others.

The people that do not move a single finger, and limit themselves
to criticizing the first ones.
 
M

Morris Dovey

jacob said:
There are two kinds of people in this world.

Absolutely. Those who think as I do, and the others. :)
The people that work, create things, offer them to the others.

The people that do not move a single finger, and limit themselves
to criticizing the first ones.

Hmm. Methinks these two groups are one - the two sides of a
single coin, so to speak. (Let's not allow ourselves to become
/too/ self-righteous.)

Kaz has offered some pretty nifty stuff here. I have some it
carefully tucked away just because it struck me as both unobvious
and elegant.

It's worth noting that the coin not only has two sides - it also
has an edge, which probably makes room for those who teach and
share their understanding with those who lack it...

....but it's still one coin.

TGIF :)
 
N

Nick Keighley

What facts? I personally got an impression that Jacob does
fix bugs. I don't have facts though.



Jacob did analyze the issue and decided there is
no bug. Wrongly, yes. But he didn't make that
decision because of who posted a "bug report". And
in his defense, most people posted in this thread
actually agreed that it's not a non-conformance bug
(which it is).

Jocob quotes:

"I am happy you do not use my compiler system since your
buggy code will not even compile"

"You can only file a bug report if you buy maintenance at premium
rates.
I have a special price for clique members sorry!"

"Yes, he can now BUY a maintenance contract and I
will do it after I receive his money ok?"


comments like "special price for clique members" imply
a different attitude to a potential bug report
depending who raised it.

Failure to accept a potential bug report from non-paying
customers sounds crazy to me! If its broken its broken.


If you can't have a kitchen sink in a compiler,
you print complex numbers. What's so hard to
understand about it? It has nothing to do with
JN's reaction to a "bug report" though.

he seems to prefer adding (low utility) features
to fixing bugs. Yes Jacob, a memory leak is a bug.


well it *is* a commercial product (which I don't
regard as a bad thing).

Yeah, "legitimate bug reports". Legitimate bug report
is when you care, not when all you want is to show
once again in comp.lang.c how much lcc-win32 sucks.

temper temper!


It's amusing how people tell JN about his discussion
style. I recall some even say that JN attacks people!
Funny.

have you read this thread?
 
A

Antoninus Twink

Kaz said:
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*]

See, this is what happens when the compiler writer becomes infatuated
with alloca. :)

There are two kinds of people in this world.

The people that work, create things, offer them to the others.

The people that do not move a single finger, and limit themselves
to criticizing the first ones.

We certainly see that clearly in clc - the Clique have nothing better to
do with their time than tut-tut and complain about top-posting or
voiding main, to provide some variety in amongst their constant savaging
of Jacob.
 
K

Kenny McCormack

IMHO, this point of view is as formalist as some about which you often
complain (again IMHO, sometimes rightfully, sometimes wrongly, but that's
another story).

Yours,

What Jacob is demonstrating (albeit subtly) is how the Clique members
act as if the standard is absolute truth (cannot be questioned and does not
need to be defended) - right up until it suits their purposes to do otherwise.

Much as religious fundy leaders do, in re: the Bible.

As I've pointed out several times previously, CLC very much resembles
fundy religion - and the temperments of the folks here closely resembles
that of Bush voters.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top