VLA Question

Discussion in 'C Programming' started by pemo, Feb 23, 2006.

  1. pemo

    pemo Guest

    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*
    ==============
    pemo, Feb 23, 2006
    #1
    1. Advertising

  2. pemo

    pemo Guest

    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*
    ==============
    pemo, Feb 23, 2006
    #2
    1. Advertising

  3. "pemo" <> 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.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Feb 23, 2006
    #3
  4. pemo

    Micah Cowan Guest

    "pemo" <> 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
    Micah Cowan, Feb 23, 2006
    #4
  5. pemo

    Michael Mair Guest

    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.
    Michael Mair, Feb 24, 2006
    #5
  6. pemo

    CBFalconer Guest

    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/>
    CBFalconer, Feb 24, 2006
    #6
  7. pemo

    pemo Guest

    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*
    ==============
    pemo, Feb 24, 2006
    #7
  8. pemo

    Robin Haigh Guest

    "pemo" <> wrote in message
    news:dtmg8l$gid$...
    > 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
    Robin Haigh, Feb 24, 2006
    #8
  9. pemo

    pemo Guest

    Robin Haigh wrote:
    > "pemo" <> wrote in message
    > news:dtmg8l$gid$...
    >> 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*
    ==============
    pemo, Feb 24, 2006
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. MackS
    Replies:
    15
    Views:
    601
    William Ahern
    Feb 21, 2005
  2. William Ahern

    Compound literals and VLA's

    William Ahern, Aug 24, 2005, in forum: C Programming
    Replies:
    6
    Views:
    695
    Robert Gamble
    Aug 24, 2005
  3. Ben Hinkle

    support of C99 VLA in compilers

    Ben Hinkle, Dec 13, 2005, in forum: C Programming
    Replies:
    6
    Views:
    704
    Jordan Abel
    Dec 15, 2005
  4. Man with Oscilloscope

    VLA and goto -- diagnostic required?

    Man with Oscilloscope, Aug 24, 2006, in forum: C Programming
    Replies:
    8
    Views:
    377
    Christopher Benson-Manica
    Aug 30, 2006
  5. Philip Lantz

    VLA question

    Philip Lantz, Jun 14, 2013, in forum: C Programming
    Replies:
    96
    Views:
    1,068
    Tim Rentsch
    Jul 14, 2013
Loading...

Share This Page