comma in a c statement, ie for(i=0,i2=0;i<10;i++,i2)

Discussion in 'C Programming' started by Test, Dec 15, 2012.

  1. Test

    Test Guest

    I have:

    for (i=0,i2=0;i<10;i++,i2++)
    {
    .. some code
    }

    Is "," (comma) oke here?

    I am converting below code to for -loop:

    i=0;
    i2=0;
    while (i<10)
    {
    ... some code
    i++;
    i2++;
    }

    Which is executed first in for (i=0,i2=0;i<10;i++,i2++)? i2=0 or i=0?

    Any caveats? I could not find explanation to comma usage (maybe not not looking
    hard enough).
     
    Test, Dec 15, 2012
    #1
    1. Advertising

  2. Test <test@.nil.invalid.com> writes:

    > I have:
    >
    > for (i=0,i2=0;i<10;i++,i2++)
    > {
    > .. some code
    > }
    >
    > Is "," (comma) oke here?


    Yes, though it's not obvious why you need both i and i2.. A few spaces
    might be a good idea, though:

    for (i = 0, i2 = 0; i < 10; i++, i2++)

    > I am converting below code to for -loop:
    >
    > i=0;
    > i2=0;
    > while (i<10)
    > {
    > ... some code
    > i++;
    > i2++;
    > }


    How odd. What's the point of have both i and i2? If either gets
    altered in the "some code" part then there is an argument for not
    re-writing it as a "for" loop. Generally, readers will expect the
    variables mentioned in a "for" loops to be left alone in the body. This
    is not rule of the language but it's a good rule of thumb.

    Note, also, that your "for" loop will not be the same as the "while"
    loop if the while loop uses "continue".

    > Which is executed first in for (i=0,i2=0;i<10;i++,i2++)? i2=0 or i=0?


    i = 0.

    > Any caveats? I could not find explanation to comma usage (maybe not
    > not looking hard enough).


    It is often considered a little confusing since the comma token has lots
    of uses in C.

    --
    Ben.
     
    Ben Bacarisse, Dec 15, 2012
    #2
    1. Advertising

  3. On Saturday, December 15, 2012 1:47:21 PM UTC, Test wrote:
    > I have:
    >
    > for (i=0,i2=0;i<10;i++,i2++)
    >
    > {
    >
    > .. some code
    >
    > }
    >
    >
    > Is "," (comma) oke here?
    >

    Yes
    >
    > Any caveats? I could not find explanation to comma usage
    >

    Comma operators are very seldom used because there's not much need for them.
    An exception is in for loops, where you might want to have two loop counters
    going at once. Even here, most C programmers prefer the style

    for(i=0;i<N;i++)
    {
    units = 0;
    tens[i*10] = 0;
    }
    --
    Visit Malcolm's homepage
    http://www.malcolmmclean.site11.com/www
     
    Malcolm McLean, Dec 15, 2012
    #3
  4. Test

    James Kuyper Guest

    On 12/15/2012 08:47 AM, Test wrote:
    > I have:
    >
    > for (i=0,i2=0;i<10;i++,i2++)
    > {
    > .. some code
    > }
    >
    > Is "," (comma) oke here?


    Yes.

    > I am converting below code to for -loop:
    >
    > i=0;
    > i2=0;
    > while (i<10)
    > {
    > ... some code
    > i++;
    > i2++;
    > }
    >
    > Which is executed first in for (i=0,i2=0;i<10;i++,i2++)? i2=0 or i=0?


    The expression i=0 is executed first, though in this particular case it
    doesn't matter.

    > Any caveats? I could not find explanation to comma usage (maybe not not looking
    > hard enough).


    The expression E1,E2, where E1 is any expression, and E2 is any
    expression other than another comma expression, causes expression E1 to
    be evaluated. The result of that evaluation is discarded, so it only
    make sense to do this if E1 is an expression with side effects, such as
    a=3, b++, or printf("error:%g", d). After all side effects of E1 are
    complete, expression E2 is evaluated. The value of expression E2 is also
    the value of the comma expression as a whole. Thus "a = (b++,c)" is
    equivalent to "b++; a=c;". It only makes sense to use a comma expression
    when such a re-write is not possible, as in a for() statement such as
    the one you ask about above.

    A key point to understand is that commas are NOT always part of a comma
    expression. The parameters of a function declaration and the arguments
    of a function call are separated by commas, and the same is true for
    function-like macros. Commas separate the initializers for the elements
    of an array or members of a structure. A single declaration can declare
    multiple declarators, separated by commas, as in "int a,b;". Commas are
    used to separate the members of a union or enumeration. Commas are also
    used in _Generic() expressions and _Static_assert() declarations, which
    are new features of C2011, syntactically similar to function calls.

    If you wish to use a comma expression in one of those contexts, you'll
    have to parenthesize it, to prevent misinterpretation of the comma.
    printf("hello %s", "world!\n") does something different from
    printf( ("hello %s", "world!\n") ).
    --
    James Kuyper
     
    James Kuyper, Dec 15, 2012
    #4
  5. Test

    James Kuyper Guest

    On 12/15/2012 08:47 AM, Test wrote:
    > I have:
    >
    > for (i=0,i2=0;i<10;i++,i2++)
    > {
    > .. some code
    > }
    >
    > Is "," (comma) oke here?


    Yes.

    > I am converting below code to for -loop:
    >
    > i=0;
    > i2=0;
    > while (i<10)
    > {
    > ... some code
    > i++;
    > i2++;
    > }
    >
    > Which is executed first in for (i=0,i2=0;i<10;i++,i2++)? i2=0 or i=0?


    The expression i=0 is executed first, though in this particular case it
    doesn't matter.

    > Any caveats? I could not find explanation to comma usage (maybe not not looking
    > hard enough).


    The expression E1,E2, where E1 is any expression, and E2 is any
    expression other than another comma expression, causes expression E1 to
    be evaluated. The result of that evaluation is discarded, so it only
    make sense to do this if E1 is an expression with side effects, such as
    a=3, b++, or printf("error:%g", d). After all side effects of E1 are
    complete, expression E2 is evaluated. The value of expression E2 is also
    the value of the comma expression as a whole. Thus "a = (b++,c)" is
    equivalent to "b++; a=c;". It only makes sense to use a comma expression
    when such a re-write is not possible, as in a for() statement such as
    the one you ask about above.

    A key point to understand is that commas are NOT always part of a comma
    expression. The parameters of a function declaration and the arguments
    of a function call are separated by commas, and the same is true for
    function-like macros. Commas separate the initializers for the elements
    of an array or members of a structure. A single declaration can declare
    multiple declarators, separated by commas, as in "int a,b;". Commas are
    used to separate the members of a union or enumeration. Commas are also
    used in _Generic() expressions and _Static_assert() declarations, which
    are new features of C2011, syntactically similar to function calls.

    If you wish to use a comma expression in one of those contexts, you'll
    have to parenthesize it, to prevent misinterpretation of the comma.
    printf("hello %s", "world!\n") does something different from
    printf( ("hello %s", "world!\n") ).
    --
    James Kuyper
     
    James Kuyper, Dec 15, 2012
    #5
  6. Test

    Les Cargill Guest

    Malcolm McLean wrote:
    > On Saturday, December 15, 2012 1:47:21 PM UTC, Test wrote:
    >> I have:
    >>
    >> for (i=0,i2=0;i<10;i++,i2++)
    >>
    >> {
    >>
    >> .. some code
    >>
    >> }
    >>
    >>
    >> Is "," (comma) oke here?
    >>

    > Yes
    >>
    >> Any caveats? I could not find explanation to comma usage
    >>

    > Comma operators are very seldom used because there's not much need for them.
    > An exception is in for loops, where you might want to have two loop counters
    > going at once. Even here, most C programmers prefer the style
    >
    > for(i=0;i<N;i++)
    > {
    > units = 0;
    > tens[i*10] = 0;
    > }
    > --
    > Visit Malcolm's homepage
    > http://www.malcolmmclean.site11.com/www
    >


    I also like:
    for(i=0;i<N;i++)
    {
    const int i2 = (i*10);
    units = 0;
    tens[i2] = 0;
    }

    which seems silly for that simple of a loop, but
    has come in handy ( especially when i2 is assigned
    from a function return )

    --
    Les Cargill
     
    Les Cargill, Dec 15, 2012
    #6
  7. James Kuyper <> writes:
    [...]
    > A key point to understand is that commas are NOT always part of a comma
    > expression. The parameters of a function declaration and the arguments
    > of a function call are separated by commas, and the same is true for
    > function-like macros. Commas separate the initializers for the elements
    > of an array or members of a structure. A single declaration can declare
    > multiple declarators, separated by commas, as in "int a,b;". Commas are
    > used to separate the members of a union or enumeration.


    How do commas separate the members of a union?

    > Commas are also
    > used in _Generic() expressions and _Static_assert() declarations, which
    > are new features of C2011, syntactically similar to function calls.

    [...]

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Dec 15, 2012
    #7
  8. Ben Bacarisse <> wrote:

    (snip)

    > How odd. What's the point of have both i and i2? If either gets
    > altered in the "some code" part then there is an argument for not
    > re-writing it as a "for" loop. Generally, readers will expect the
    > variables mentioned in a "for" loops to be left alone in the body. This
    > is not rule of the language but it's a good rule of thumb.


    I have used "for" loops where I needed "continue" to restart
    the loop without incrementing the index.

    Otherwise, I agree.

    -- glen
     
    glen herrmannsfeldt, Dec 15, 2012
    #8
  9. glen herrmannsfeldt <> writes:

    > Ben Bacarisse <> wrote:
    >
    > (snip)
    >
    >> How odd. What's the point of have both i and i2? If either gets
    >> altered in the "some code" part then there is an argument for not
    >> re-writing it as a "for" loop. Generally, readers will expect the
    >> variables mentioned in a "for" loops to be left alone in the body. This
    >> is not rule of the language but it's a good rule of thumb.

    >
    > I have used "for" loops where I needed "continue" to restart
    > the loop without incrementing the index.
    >
    > Otherwise, I agree.


    So when you want that behaviour you'd write:

    for (<initialise>; <condition>;) {
    <code that uses continue>
    <increment>
    }

    rather than

    <initialise>
    while (<condition>) {
    <code that uses continue>
    <increment>
    }

    ? I don't think I would (and I could make hand-waving arguments about
    why I wouldn't) but it's really just a matter to taste.

    --
    Ben.
     
    Ben Bacarisse, Dec 15, 2012
    #9
  10. Test

    Les Cargill Guest

    Ben Bacarisse wrote:
    > glen herrmannsfeldt <> writes:
    >
    >> Ben Bacarisse <> wrote:
    >>
    >> (snip)
    >>
    >>> How odd. What's the point of have both i and i2? If either gets
    >>> altered in the "some code" part then there is an argument for not
    >>> re-writing it as a "for" loop. Generally, readers will expect the
    >>> variables mentioned in a "for" loops to be left alone in the body. This
    >>> is not rule of the language but it's a good rule of thumb.

    >>
    >> I have used "for" loops where I needed "continue" to restart
    >> the loop without incrementing the index.
    >>
    >> Otherwise, I agree.

    >
    > So when you want that behaviour you'd write:
    >
    > for (<initialise>; <condition>;) {
    > <code that uses continue>
    > <increment>
    > }
    >
    > rather than
    >
    > <initialise>
    > while (<condition>) {
    > <code that uses continue>
    > <increment>
    > }
    >
    > ? I don't think I would (and I could make hand-waving arguments about
    > why I wouldn't) but it's really just a matter to taste.
    >



    As soon as you need a break or continue in the for loop, my
    heuristic is to go with a while. But I'm not always consistent
    about it...

    --
    Les Cargill
     
    Les Cargill, Dec 15, 2012
    #10
  11. Test

    Shao Miller Guest

    On 12/15/2012 15:47, Ben Bacarisse wrote:
    > glen herrmannsfeldt <> writes:
    >
    >> Ben Bacarisse <> wrote:
    >>
    >> (snip)
    >>
    >>> How odd. What's the point of have both i and i2? If either gets
    >>> altered in the "some code" part then there is an argument for not
    >>> re-writing it as a "for" loop. Generally, readers will expect the
    >>> variables mentioned in a "for" loops to be left alone in the body. This
    >>> is not rule of the language but it's a good rule of thumb.

    >>
    >> I have used "for" loops where I needed "continue" to restart
    >> the loop without incrementing the index.
    >>
    >> Otherwise, I agree.

    >
    > So when you want that behaviour you'd write:
    >
    > for (<initialise>; <condition>;) {
    > <code that uses continue>
    > <increment>
    > }
    >
    > rather than
    >
    > <initialise>
    > while (<condition>) {
    > <code that uses continue>
    > <increment>
    > }
    >
    > ? I don't think I would (and I could make hand-waving arguments about
    > why I wouldn't) but it's really just a matter to taste.
    >


    It can also be a matter of lifetime (for C >= C99), which could
    potentially impact memory usage. By using declarations (but not
    compound literals) in the 'for', such objects needn't've storage for the
    enclosing block.

    - Shao Miller
     
    Shao Miller, Dec 15, 2012
    #11
  12. Test

    James Kuyper Guest

    On 12/15/2012 03:21 PM, Keith Thompson wrote:
    > James Kuyper <> writes:

    ....
    >> ... Commas are
    >> used to separate the members of a union or enumeration.

    >
    > How do commas separate the members of a union?


    They don't - that comment started life as a very different statement
    about structs, unions, and enumerations, and I forgot to remove the part
    about unions when I did a major re-write of the statement that rendered
    it no longer applicable to unions. Sorry for the confusion (I don't
    expect that you were confused, but the OP might have been).
    --
    James Kuyper
     
    James Kuyper, Dec 15, 2012
    #12
  13. Ben Bacarisse <> wrote:

    (snip on the comma operator used in for loops, then I wrote)

    >> I have used "for" loops where I needed "continue" to restart
    >> the loop without incrementing the index.


    >> Otherwise, I agree.


    > So when you want that behaviour you'd write:


    > for (<initialise>; <condition>;) {
    > <code that uses continue>
    > <increment>
    > }


    > rather than


    > <initialise>
    > while (<condition>) {
    > <code that uses continue>
    > <increment>
    > }


    It might have started out as a normal "for" loop before I realized
    that the "continue" was needed, but yes. As long as the initialization
    was related to the loop, I would probably use for.

    I tend to use "while" where the condition is a function call, not
    a test on a loop variable, such as with fgets().

    > ? I don't think I would (and I could make hand-waving arguments about
    > why I wouldn't) but it's really just a matter to taste.


    -- glen
     
    glen herrmannsfeldt, Dec 15, 2012
    #13
  14. Shao Miller <> writes:

    > On 12/15/2012 15:47, Ben Bacarisse wrote:
    >> glen herrmannsfeldt <> writes:
    >>
    >>> Ben Bacarisse <> wrote:
    >>>
    >>> (snip)
    >>>
    >>>> How odd. What's the point of have both i and i2? If either gets
    >>>> altered in the "some code" part then there is an argument for not
    >>>> re-writing it as a "for" loop. Generally, readers will expect the
    >>>> variables mentioned in a "for" loops to be left alone in the body. This
    >>>> is not rule of the language but it's a good rule of thumb.
    >>>
    >>> I have used "for" loops where I needed "continue" to restart
    >>> the loop without incrementing the index.
    >>>
    >>> Otherwise, I agree.

    >>
    >> So when you want that behaviour you'd write:
    >>
    >> for (<initialise>; <condition>;) {
    >> <code that uses continue>
    >> <increment>
    >> }
    >>
    >> rather than
    >>
    >> <initialise>
    >> while (<condition>) {
    >> <code that uses continue>
    >> <increment>
    >> }
    >>
    >> ? I don't think I would (and I could make hand-waving arguments about
    >> why I wouldn't) but it's really just a matter to taste.
    >>

    >
    > It can also be a matter of lifetime (for C >= C99), which could
    > potentially impact memory usage. By using declarations (but not
    > compound literals) in the 'for', such objects needn't've storage for
    > the enclosing block.


    That does not match my understanding. Can you provide supporting
    evidence?

    Putting a declaration in a for statement (as opposed to just before a
    while) alters the scope the scope of the name but does not, I think,
    have any effect on the lifetime of the declared object.

    --
    Ben.
     
    Ben Bacarisse, Dec 15, 2012
    #14
  15. Test

    Shao Miller Guest

    On 12/15/2012 17:10, Ben Bacarisse wrote:
    > Shao Miller <> writes:
    >
    >> On 12/15/2012 15:47, Ben Bacarisse wrote:
    >>> glen herrmannsfeldt <> writes:
    >>>
    >>>> Ben Bacarisse <> wrote:
    >>>>
    >>>> (snip)
    >>>>
    >>>>> How odd. What's the point of have both i and i2? If either gets
    >>>>> altered in the "some code" part then there is an argument for not
    >>>>> re-writing it as a "for" loop. Generally, readers will expect the
    >>>>> variables mentioned in a "for" loops to be left alone in the body. This
    >>>>> is not rule of the language but it's a good rule of thumb.
    >>>>
    >>>> I have used "for" loops where I needed "continue" to restart
    >>>> the loop without incrementing the index.
    >>>>
    >>>> Otherwise, I agree.
    >>>
    >>> So when you want that behaviour you'd write:
    >>>
    >>> for (<initialise>; <condition>;) {
    >>> <code that uses continue>
    >>> <increment>
    >>> }
    >>>
    >>> rather than
    >>>
    >>> <initialise>
    >>> while (<condition>) {
    >>> <code that uses continue>
    >>> <increment>
    >>> }
    >>>
    >>> ? I don't think I would (and I could make hand-waving arguments about
    >>> why I wouldn't) but it's really just a matter to taste.
    >>>

    >>
    >> It can also be a matter of lifetime (for C >= C99), which could
    >> potentially impact memory usage. By using declarations (but not
    >> compound literals) in the 'for', such objects needn't've storage for
    >> the enclosing block.

    >
    > That does not match my understanding. Can you provide supporting
    > evidence?
    >
    > Putting a declaration in a for statement (as opposed to just before a
    > while) alters the scope the scope of the name but does not, I think,
    > have any effect on the lifetime of the declared object.
    >


    Sure thing. C99 6.8.5.3p1 with 6.2.4p6.

    Personally, these days I like to declare everything at the top of a
    function, so I don't actually take advantage of this, but it might be
    worth noting, for C >= C99.

    - Shao Miller
     
    Shao Miller, Dec 15, 2012
    #15
  16. Shao Miller <> writes:
    > On 12/15/2012 17:10, Ben Bacarisse wrote:
    >> Shao Miller <> writes:
    >>> On 12/15/2012 15:47, Ben Bacarisse wrote:
    >>>> glen herrmannsfeldt <> writes:

    [...]
    >>>>> I have used "for" loops where I needed "continue" to restart
    >>>>> the loop without incrementing the index.
    >>>>>
    >>>>> Otherwise, I agree.
    >>>>
    >>>> So when you want that behaviour you'd write:
    >>>>
    >>>> for (<initialise>; <condition>;) {
    >>>> <code that uses continue>
    >>>> <increment>
    >>>> }
    >>>>
    >>>> rather than
    >>>>
    >>>> <initialise>
    >>>> while (<condition>) {
    >>>> <code that uses continue>
    >>>> <increment>
    >>>> }
    >>>>
    >>>> ? I don't think I would (and I could make hand-waving arguments about
    >>>> why I wouldn't) but it's really just a matter to taste.
    >>>>
    >>>
    >>> It can also be a matter of lifetime (for C >= C99), which could
    >>> potentially impact memory usage. By using declarations (but not
    >>> compound literals) in the 'for', such objects needn't've storage for
    >>> the enclosing block.

    >>
    >> That does not match my understanding. Can you provide supporting
    >> evidence?
    >>
    >> Putting a declaration in a for statement (as opposed to just before a
    >> while) alters the scope the scope of the name but does not, I think,
    >> have any effect on the lifetime of the declared object.
    >>

    >
    > Sure thing. C99 6.8.5.3p1 with 6.2.4p6.
    >
    > Personally, these days I like to declare everything at the top of a
    > function, so I don't actually take advantage of this, but it might be
    > worth noting, for C >= C99.


    6.8.5.3p1:
    If *clause-1* is a declaration, the scope of any identifiers
    it declares is the remainder of the declaration and the entire
    loop, including the other two expressions

    6.2.4p6:
    For such an object that does not have a variable length array type,
    its lifetime extends from entry into the block with which it is
    associated until execution of that block ends in any way.

    So my interpretation of that is:

    void foo(void) { /* lifetime of i starts here */
    this();
    that();
    for (int i = 0 /* scope of i starts here */; i < 100; i ++) {
    the_other_thing(i);
    /* scope of i ends here */
    }
    yet_another_thing();
    /* lifetime of i ends here */
    }

    The "block with which it is associated" is the outer block for the
    function, not the block that is the statement controlled by the for
    loop.

    Remember that the statement controlled by a for loop needn't be a block:

    for (int i = 0; i < 100; i ++)
    single_statement();

    If `i` were defined just above the for loop, the lifetime and scope would
    be the same as they are in my example.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Dec 15, 2012
    #16
  17. Shao Miller <> writes:

    > On 12/15/2012 17:10, Ben Bacarisse wrote:
    >> Shao Miller <> writes:
    >>
    >>> On 12/15/2012 15:47, Ben Bacarisse wrote:
    >>>> glen herrmannsfeldt <> writes:
    >>>>
    >>>>> Ben Bacarisse <> wrote:
    >>>>>
    >>>>> (snip)
    >>>>>
    >>>>>> How odd. What's the point of have both i and i2? If either gets
    >>>>>> altered in the "some code" part then there is an argument for not
    >>>>>> re-writing it as a "for" loop. Generally, readers will expect the
    >>>>>> variables mentioned in a "for" loops to be left alone in the body. This
    >>>>>> is not rule of the language but it's a good rule of thumb.
    >>>>>
    >>>>> I have used "for" loops where I needed "continue" to restart
    >>>>> the loop without incrementing the index.
    >>>>>
    >>>>> Otherwise, I agree.
    >>>>
    >>>> So when you want that behaviour you'd write:
    >>>>
    >>>> for (<initialise>; <condition>;) {
    >>>> <code that uses continue>
    >>>> <increment>
    >>>> }
    >>>>
    >>>> rather than
    >>>>
    >>>> <initialise>
    >>>> while (<condition>) {
    >>>> <code that uses continue>
    >>>> <increment>
    >>>> }
    >>>>
    >>>> ? I don't think I would (and I could make hand-waving arguments about
    >>>> why I wouldn't) but it's really just a matter to taste.
    >>>>
    >>>
    >>> It can also be a matter of lifetime (for C >= C99), which could
    >>> potentially impact memory usage. By using declarations (but not
    >>> compound literals) in the 'for', such objects needn't've storage for
    >>> the enclosing block.

    >>
    >> That does not match my understanding. Can you provide supporting
    >> evidence?
    >>
    >> Putting a declaration in a for statement (as opposed to just before a
    >> while) alters the scope the scope of the name but does not, I think,
    >> have any effect on the lifetime of the declared object.

    >
    > Sure thing. C99 6.8.5.3p1 with 6.2.4p6.


    These support exactly what I said. I don't see any support there for
    the change in the lifetime that you suggested.

    --
    Ben.
     
    Ben Bacarisse, Dec 16, 2012
    #17
  18. Test

    Shao Miller Guest

    On 12/15/2012 18:43, Keith Thompson wrote:
    > Shao Miller <> writes:
    >> On 12/15/2012 17:10, Ben Bacarisse wrote:
    >>> Shao Miller <> writes:
    >>>> On 12/15/2012 15:47, Ben Bacarisse wrote:
    >>>>> glen herrmannsfeldt <> writes:

    > [...]
    >>>>>> I have used "for" loops where I needed "continue" to restart
    >>>>>> the loop without incrementing the index.
    >>>>>>
    >>>>>> Otherwise, I agree.
    >>>>>
    >>>>> So when you want that behaviour you'd write:
    >>>>>
    >>>>> for (<initialise>; <condition>;) {
    >>>>> <code that uses continue>
    >>>>> <increment>
    >>>>> }
    >>>>>
    >>>>> rather than
    >>>>>
    >>>>> <initialise>
    >>>>> while (<condition>) {
    >>>>> <code that uses continue>
    >>>>> <increment>
    >>>>> }
    >>>>>
    >>>>> ? I don't think I would (and I could make hand-waving arguments about
    >>>>> why I wouldn't) but it's really just a matter to taste.
    >>>>>
    >>>>
    >>>> It can also be a matter of lifetime (for C >= C99), which could
    >>>> potentially impact memory usage. By using declarations (but not
    >>>> compound literals) in the 'for', such objects needn't've storage for
    >>>> the enclosing block.
    >>>
    >>> That does not match my understanding. Can you provide supporting
    >>> evidence?
    >>>
    >>> Putting a declaration in a for statement (as opposed to just before a
    >>> while) alters the scope the scope of the name but does not, I think,
    >>> have any effect on the lifetime of the declared object.
    >>>

    >>
    >> Sure thing. C99 6.8.5.3p1 with 6.2.4p6.
    >>
    >> Personally, these days I like to declare everything at the top of a
    >> function, so I don't actually take advantage of this, but it might be
    >> worth noting, for C >= C99.

    >
    > 6.8.5.3p1:
    > If *clause-1* is a declaration, the scope of any identifiers
    > it declares is the remainder of the declaration and the entire
    > loop, including the other two expressions
    >
    > 6.2.4p6:
    > For such an object that does not have a variable length array type,
    > its lifetime extends from entry into the block with which it is
    > associated until execution of that block ends in any way.
    >


    I must _sincerely_ apologize. This must be a circumstance where
    N1256.PDF differs from C99. Please forgive me for referring to the
    wrong point! N1256.PDF's 6.2.4p6:

    "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.27) If the scope is
    entered recursively, a new instance of the object is created each time.
    The initial value of the object is indeterminate."

    > So my interpretation of that is:
    >
    > void foo(void) { /* lifetime of i starts here */
    > this();
    > that();
    > for (int i = 0 /* scope of i starts here */; i < 100; i ++) {
    > the_other_thing(i);
    > /* scope of i ends here */
    > }
    > yet_another_thing();
    > /* lifetime of i ends here */
    > }
    >
    > The "block with which it is associated" is the outer block for the
    > function, not the block that is the statement controlled by the for
    > loop.
    >
    > Remember that the statement controlled by a for loop needn't be a block:
    >
    > for (int i = 0; i < 100; i ++)
    > single_statement();
    >
    > If `i` were defined just above the for loop, the lifetime and scope would
    > be the same as they are in my example.
    >


    Because VLAs are the predominant feature for C99 from my perspective, I
    realize now that I've actually skipped mentioning them, but they are
    precisely what I'm referring to.

    - Shao Miller
     
    Shao Miller, Dec 16, 2012
    #18
  19. Test

    Shao Miller Guest

    On 12/15/2012 20:24, Ben Bacarisse wrote:
    > Shao Miller <> writes:
    >
    >> On 12/15/2012 17:10, Ben Bacarisse wrote:
    >>> Shao Miller <> writes:
    >>>
    >>>> On 12/15/2012 15:47, Ben Bacarisse wrote:
    >>>>> glen herrmannsfeldt <> writes:
    >>>>>
    >>>>>> Ben Bacarisse <> wrote:
    >>>>>>
    >>>>>> (snip)
    >>>>>>
    >>>>>>> How odd. What's the point of have both i and i2? If either gets
    >>>>>>> altered in the "some code" part then there is an argument for not
    >>>>>>> re-writing it as a "for" loop. Generally, readers will expect the
    >>>>>>> variables mentioned in a "for" loops to be left alone in the body. This
    >>>>>>> is not rule of the language but it's a good rule of thumb.
    >>>>>>
    >>>>>> I have used "for" loops where I needed "continue" to restart
    >>>>>> the loop without incrementing the index.
    >>>>>>
    >>>>>> Otherwise, I agree.
    >>>>>
    >>>>> So when you want that behaviour you'd write:
    >>>>>
    >>>>> for (<initialise>; <condition>;) {
    >>>>> <code that uses continue>
    >>>>> <increment>
    >>>>> }
    >>>>>
    >>>>> rather than
    >>>>>
    >>>>> <initialise>
    >>>>> while (<condition>) {
    >>>>> <code that uses continue>
    >>>>> <increment>
    >>>>> }
    >>>>>
    >>>>> ? I don't think I would (and I could make hand-waving arguments about
    >>>>> why I wouldn't) but it's really just a matter to taste.
    >>>>>
    >>>>
    >>>> It can also be a matter of lifetime (for C >= C99), which could
    >>>> potentially impact memory usage. By using declarations (but not
    >>>> compound literals) in the 'for', such objects needn't've storage for
    >>>> the enclosing block.
    >>>
    >>> That does not match my understanding. Can you provide supporting
    >>> evidence?
    >>>
    >>> Putting a declaration in a for statement (as opposed to just before a
    >>> while) alters the scope the scope of the name but does not, I think,
    >>> have any effect on the lifetime of the declared object.

    >>
    >> Sure thing. C99 6.8.5.3p1 with 6.2.4p6.

    >
    > These support exactly what I said. I don't see any support there for
    > the change in the lifetime that you suggested.
    >


    With _much_ apology, I've assumed that N1256.PDF's 6.2.4p6 is C99's. I
    am referring to C99's VLAs, which obviously introduce a number of quirks
    (relative to C89/C90). One of those quirks is that their lifetime and
    scope are fairly closely tied, and it's relevant for a 'for' loop's
    clause-1. (_Why_ one would declare a VLA in a 'for' loop is a matter of
    practicality, but _that_ one can is a matter of fact.)

    Or, I could be missing something.

    - Shao Miller
     
    Shao Miller, Dec 16, 2012
    #19
  20. Test

    Philip Lantz Guest

    Keith Thompson wrote:
    >
    > James Kuyper <> writes:
    > [...]
    > > A key point to understand is that commas are NOT always part of a comma
    > > expression. The parameters of a function declaration and the arguments
    > > of a function call are separated by commas, and the same is true for
    > > function-like macros. Commas separate the initializers for the elements
    > > of an array or members of a structure. A single declaration can declare
    > > multiple declarators, separated by commas, as in "int a,b;". Commas are
    > > used to separate the members of a union or enumeration.

    >
    > How do commas separate the members of a union?


    union u {
    int x, y;
    };

    :)
     
    Philip Lantz, Dec 16, 2012
    #20
    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. Replies:
    3
    Views:
    817
  2. Jay McGavren
    Replies:
    11
    Views:
    1,157
    Alan Krueger
    Jan 16, 2006
  3. tedsuzman
    Replies:
    2
    Views:
    7,124
    Michel Claveau, résurectionné d'outre-bombe inform
    Jul 21, 2004
  4. Ted
    Replies:
    1
    Views:
    478
    Duncan Booth
    Jul 22, 2004
  5. Adee

    Comma inside if statement in C

    Adee, Feb 14, 2013, in forum: C Programming
    Replies:
    18
    Views:
    498
    Keith Thompson
    Feb 17, 2013
Loading...

Share This Page