Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > VLA Question

Reply
Thread Tools

VLA Question

 
 
pemo
Guest
Posts: n/a
 
      02-23-2006
Couple of questions about the following code (playing with variable length
arrays):

#include <stdio.h>
#include <string.h>

void f(int n, char * argv[])
{
again:

{
char c[n++];

// puts(c);

if(strlen(argv[0]) > n + 1)
{
goto again;
}

else

{
strcpy(c, argv[0]);

puts(c);
}
}

return;

}

int main(int argc, char * argv[])
{
f(0, argv);

getchar();

return 0;
}

1. My understanding of vla is that 'c' should be destroyed/recreated each
time I jump to again: This seems to be the case - uncomment the //
puts(c) - with gcc, 'c' indeed contains garbage each time [a bit of a 'risky
test', but worth it I thought].

Anyway, is my understanding correct here, e.g., that the code is working as
the c99 std says it should?

2. If you were to remove the compound statement[ the { before char c[n++];
and the } before the return; ], gcc gives an error:

'syntax error before "char"'

It obviously doesn't like a definition appearing after a label.

That surprised me, and I'm not sure that it's correct, i.e., I haven't yet
found anything in the stds that says this is defined behaviour. Opinions?


--
==============
*Not a pedant*
==============


 
Reply With Quote
 
 
 
 
pemo
Guest
Posts: n/a
 
      02-23-2006
pemo wrote:
> Couple of questions about the following code (playing with variable
> length arrays):
>
> #include <stdio.h>
> #include <string.h>
>
> void f(int n, char * argv[])
> {
> again:
>
> {
> char c[n++];
>
> // puts(c);
>
> if(strlen(argv[0]) > n + 1)
> {
> goto again;
> }
>
> else
>
> {
> strcpy(c, argv[0]);
>
> puts(c);
> }
> }
>
> return;
>
> }
>
> int main(int argc, char * argv[])
> {
> f(0, argv);
>
> getchar();
>
> return 0;
> }
>
> 1. My understanding of vla is that 'c' should be destroyed/recreated
> each time I jump to again: This seems to be the case - uncomment the
> // puts(c) - with gcc, 'c' indeed contains garbage each time [a bit of a
> 'risky test', but worth it I thought].
>
> Anyway, is my understanding correct here, e.g., that the code is
> working as the c99 std says it should?
>
> 2. If you were to remove the compound statement[ the { before char
> c[n++]; and the } before the return; ], gcc gives an error:
>
> 'syntax error before "char"'
>
> It obviously doesn't like a definition appearing after a label.
>
> That surprised me, and I'm not sure that it's correct, i.e., I
> haven't yet found anything in the stds that says this is defined
> behaviour. Opinions?


Duh, that should have been something more like ...

{
char c[n++];

puts(c);

c[0] = 'Z';

gcc seemingly preserves the contents [mostly].

BN+w=?@ <- initial entry: garbage.
ZN+w=?@ <- after initial c[0] = 'Z': mostly garbage.
->= <- hmmm
Z>= <- Zs from here on in: mostly garbage.
Z>=
Z>=
Z>=
Z>= -- "" --
Z>=
Z>=
Z>=
Z>=
Z>=
vla <- after the strcpy.


--
==============
*Not a pedant*
==============


 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      02-23-2006
"pemo" <(E-Mail Removed)> writes:
[snip]
> 2. If you were to remove the compound statement[ the { before char c[n++];
> and the } before the return; ], gcc gives an error:
>
> 'syntax error before "char"'
>
> It obviously doesn't like a definition appearing after a label.
>
> That surprised me, and I'm not sure that it's correct, i.e., I haven't yet
> found anything in the stds that says this is defined behaviour. Opinions?


I know the answer to that, but there's no way I can explain it without
being a pedant, and I know how much you hate that. Sorry.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Micah Cowan
Guest
Posts: n/a
 
      02-23-2006
"pemo" <(E-Mail Removed)> writes:

> pemo wrote:
> > Couple of questions about the following code (playing with variable
> > length arrays):
> >
> > #include <stdio.h>
> > #include <string.h>
> >
> > void f(int n, char * argv[])
> > {
> > again:
> >
> > {
> > char c[n++];
> >
> > // puts(c);
> >
> > if(strlen(argv[0]) > n + 1)
> > {
> > goto again;
> > }
> >
> > else
> >
> > {
> > strcpy(c, argv[0]);
> >
> > puts(c);
> > }
> > }
> >
> > return;
> >
> > }
> >
> > int main(int argc, char * argv[])
> > {
> > f(0, argv);
> >
> > getchar();
> >
> > return 0;
> > }
> >
> > 1. My understanding of vla is that 'c' should be destroyed/recreated
> > each time I jump to again: This seems to be the case - uncomment the
> > // puts(c) - with gcc, 'c' indeed contains garbage each time [a bit of a
> > 'risky test', but worth it I thought].
> >
> > Anyway, is my understanding correct here, e.g., that the code is
> > working as the c99 std says it should?


Yes. The lifetiem of a VLA extends from its declaration to the end of
the block.

> >
> > 2. If you were to remove the compound statement[ the { before char
> > c[n++]; and the } before the return; ], gcc gives an error:
> >
> > 'syntax error before "char"'
> >
> > It obviously doesn't like a definition appearing after a label.
> >
> > That surprised me, and I'm not sure that it's correct, i.e., I
> > haven't yet found anything in the stds that says this is defined
> > behaviour. Opinions?


This is one of the known differences between the way intermixed
declarations/statements work in C and how they work in C++. In C++, a
declaration can be a statement, in its own right. In C, declarations
are still not statements; they just can appear with statements in any
order within a complex statement.

To make it work, you can use a null statement...

again:
;
char c[n++];

<what follows is your response to your own message>:

> Duh, that should have been something more like ...
>
> {
> char c[n++];
>
> puts(c);
>
> c[0] = 'Z';
>
> gcc seemingly preserves the contents [mostly].
>
> BN+w=?@ <- initial entry: garbage.
> ZN+w=?@ <- after initial c[0] = 'Z': mostly garbage.
> ->= <- hmmm
> Z>= <- Zs from here on in: mostly garbage.
> Z>=
> Z>=
> Z>=
> Z>= -- "" --
> Z>=
> Z>=
> Z>=
> Z>=
> Z>=
> vla <- after the strcpy.


Of course, you realize that running the code like that at all is quite
undefined behavior. Really, at the very least you should set an
element to '\0'.

-Micah
 
Reply With Quote
 
Michael Mair
Guest
Posts: n/a
 
      02-24-2006
pemo schrieb:
> Couple of questions about the following code (playing with variable length
> arrays):
>
> #include <stdio.h>
> #include <string.h>
>
> void f(int n, char * argv[])
> {
> again:
>
> {
> char c[n++];
>
> // puts(c);
>
> if(strlen(argv[0]) > n + 1)


ITYM strlen(argv[0]) + 1 > n

> {
> goto again;
> }
>
> else
>
> {
> strcpy(c, argv[0]);
>
> puts(c);
> }
> }
>
> return;
>
> }
>
> int main(int argc, char * argv[])
> {
> f(0, argv);
>
> getchar();
>
> return 0;
> }
>
> 1. My understanding of vla is that 'c' should be destroyed/recreated each
> time I jump to again: This seems to be the case - uncomment the //
> puts(c) - with gcc, 'c' indeed contains garbage each time [a bit of a 'risky
> test', but worth it I thought].
>
> Anyway, is my understanding correct here, e.g., that the code is working as
> the c99 std says it should?
>
> 2. If you were to remove the compound statement[ the { before char c[n++];
> and the } before the return; ], gcc gives an error:
>
> 'syntax error before "char"'
>
> It obviously doesn't like a definition appearing after a label.
>
> That surprised me, and I'm not sure that it's correct, i.e., I haven't yet
> found anything in the stds that says this is defined behaviour. Opinions?


Have a look at the C99 grammar.
Declarations are not statements, but labels have to precede statements.
You can try the very same with case labels...

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      02-24-2006
Keith Thompson wrote:
>

.... snip ...
>
> I know the answer to that, but there's no way I can explain it
> without being a pedant, and I know how much you hate that. Sorry.


Laughing all the way to the bank.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>


 
Reply With Quote
 
pemo
Guest
Posts: n/a
 
      02-24-2006
Michael Mair wrote:
> pemo schrieb:
>> Couple of questions about the following code (playing with variable
>> length arrays):
>>
>> #include <stdio.h>
>> #include <string.h>
>>
>> void f(int n, char * argv[])
>> {
>> again:
>>
>> {
>> char c[n++];
>>
>> // puts(c);
>>
>> if(strlen(argv[0]) > n + 1)

>
> ITYM strlen(argv[0]) + 1 > n
>
>> {
>> goto again;
>> }
>>
>> else
>>
>> {
>> strcpy(c, argv[0]);
>>
>> puts(c);
>> }
>> }
>>
>> return;
>>
>> }
>>
>> int main(int argc, char * argv[])
>> {
>> f(0, argv);
>>
>> getchar();
>>
>> return 0;
>> }
>>
>> 1. My understanding of vla is that 'c' should be destroyed/recreated
>> each time I jump to again: This seems to be the case - uncomment
>> the // puts(c) - with gcc, 'c' indeed contains garbage each time [a bit
>> of
>> a 'risky test', but worth it I thought].
>>
>> Anyway, is my understanding correct here, e.g., that the code is
>> working as the c99 std says it should?
>>
>> 2. If you were to remove the compound statement[ the { before char
>> c[n++]; and the } before the return; ], gcc gives an error:
>>
>> 'syntax error before "char"'
>>
>> It obviously doesn't like a definition appearing after a label.
>>
>> That surprised me, and I'm not sure that it's correct, i.e., I
>> haven't yet found anything in the stds that says this is defined
>> behaviour. Opinions?

>
> Have a look at the C99 grammar.
> Declarations are not statements, but labels have to precede
> statements. You can try the very same with case labels...



> Have a look at the C99 grammar.
> Declarations are not statements, but labels have to precede
> statements. You can try the very same with case labels...


Yes thanks, I fathomed this out just after I posted!

>>ITYM strlen(argv[0]) + 1 > n


Nice catch, thanks.


--
==============
*Not a pedant*
==============


 
Reply With Quote
 
Robin Haigh
Guest
Posts: n/a
 
      02-24-2006

"pemo" <(E-Mail Removed)> wrote in message
news:dtmg8l$gid$(E-Mail Removed)...
> Michael Mair wrote:
> > pemo schrieb:
> >> Couple of questions about the following code (playing with variable
> >> length arrays):
> >>
> >> #include <stdio.h>
> >> #include <string.h>
> >>
> >> void f(int n, char * argv[])
> >> {
> >> again:
> >>
> >> {
> >> char c[n++];
> >>
> >> // puts(c);
> >>
> >> if(strlen(argv[0]) > n + 1)

> >
> > ITYM strlen(argv[0]) + 1 > n
> >
> >> {
> >> goto again;
> >> }
> >>
> >> else
> >>
> >> {
> >> strcpy(c, argv[0]);
> >>
> >> puts(c);
> >> }
> >> }
> >>
> >> return;
> >>
> >> }
> >>
> >> int main(int argc, char * argv[])
> >> {
> >> f(0, argv);
> >>
> >> getchar();
> >>
> >> return 0;
> >> }
> >>
> >>
> >> [snip]
> >>

> Yes thanks, I fathomed this out just after I posted!
>
> >>ITYM strlen(argv[0]) + 1 > n

>
> Nice catch, thanks.



And moreover, the definition needs to be char c[++n] not n++, or you're
still a byte short

--
RSH


 
Reply With Quote
 
pemo
Guest
Posts: n/a
 
      02-24-2006
Robin Haigh wrote:
> "pemo" <(E-Mail Removed)> wrote in message
> news:dtmg8l$gid$(E-Mail Removed)...
>> Michael Mair wrote:
>>> pemo schrieb:
>>>> Couple of questions about the following code (playing with variable
>>>> length arrays):
>>>>
>>>> #include <stdio.h>
>>>> #include <string.h>
>>>>
>>>> void f(int n, char * argv[])
>>>> {
>>>> again:
>>>>
>>>> {
>>>> char c[n++];
>>>>
>>>> // puts(c);
>>>>
>>>> if(strlen(argv[0]) > n + 1)
>>>
>>> ITYM strlen(argv[0]) + 1 > n
>>>
>>>> {
>>>> goto again;
>>>> }
>>>>
>>>> else
>>>>
>>>> {
>>>> strcpy(c, argv[0]);
>>>>
>>>> puts(c);
>>>> }
>>>> }
>>>>
>>>> return;
>>>>
>>>> }
>>>>
>>>> int main(int argc, char * argv[])
>>>> {
>>>> f(0, argv);
>>>>
>>>> getchar();
>>>>
>>>> return 0;
>>>> }
>>>>
>>>>
>>>> [snip]
>>>>

>> Yes thanks, I fathomed this out just after I posted!
>>
>>>> ITYM strlen(argv[0]) + 1 > n

>>
>> Nice catch, thanks.

>
>
> And moreover, the definition needs to be char c[++n] not n++, or
> you're still a byte short


Ta - that's me, one byte short of a full array!

--
==============
*Not a pedant*
==============


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Routing Between Two VLA Ns Bob Simon Cisco 5 02-06-2007 01:15 AM
VLA and goto -- diagnostic required? Man with Oscilloscope C Programming 8 08-30-2006 08:41 PM
support of C99 VLA in compilers Ben Hinkle C Programming 6 12-15-2005 02:08 PM
Compound literals and VLA's William Ahern C Programming 6 08-24-2005 05:40 AM
[C99] local VLA with dimension given by a global var? MackS C Programming 15 02-21-2005 07:59 PM



Advertisments