VLA Question

P

pemo

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?
 
P

pemo

pemo said:
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.
 
K

Keith Thompson

pemo said:
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.
 
M

Micah Cowan

pemo said:
pemo said:
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++];

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
 
M

Michael Mair

pemo said:
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
 
C

CBFalconer

Keith said:
.... 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/>
 
P

pemo

Michael said:
pemo said:
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.
 
R

Robin Haigh

pemo said:
Michael said:
pemo said:
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
 
P

pemo

Robin said:
pemo said:
Michael said:
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!
 

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

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top