difference between *ptr++ and ++*ptr ?

Discussion in 'C Programming' started by Jason, May 15, 2005.

  1. Jason

    Jason Guest

    Hello,

    could someone explain the difference to me inbetween:
    *ptr++ and ++*ptr

    Thankx a lot..

    Jason.
     
    Jason, May 15, 2005
    #1
    1. Advertising

  2. Jason

    Eric Sosman Guest

    Jason wrote:
    > Hello,
    >
    > could someone explain the difference to me inbetween:
    > *ptr++ and ++*ptr


    *ptr++ means "Fetch the thing that `ptr' points to, and
    increment `ptr' so it points to the next thing."

    ++*ptr means "Increment the thing `ptr' points to, and
    leave `ptr' itself unchanged."

    --
     
    Eric Sosman, May 15, 2005
    #2
    1. Advertising

  3. Eric Sosman wrote:
    > Jason wrote:
    >
    >> Hello,
    >>
    >> could someone explain the difference to me inbetween:
    >> *ptr++ and ++*ptr

    >
    >
    > *ptr++ means "Fetch the thing that `ptr' points to, and
    > increment `ptr' so it points to the next thing."
    >
    > ++*ptr means "Increment the thing `ptr' points to, and
    > leave `ptr' itself unchanged."
    >


    The second expression is unambiguous even if you don't remember the
    precedence rules or evaluation order. When it comes to the first
    expression I'd increment ptr in a separate statement (even though most C
    programmers love multiple side-effects).


    -- August
     
    August Karlstrom, May 15, 2005
    #3
  4. Jason

    Jason Guest

    On Sun, 15 May 2005 15:09:49 GMT, August Karlstrom
    <> wrote:

    > Eric Sosman wrote:
    > > Jason wrote:
    > >
    > >> Hello,
    > >>
    > >> could someone explain the difference to me inbetween:
    > >> *ptr++ and ++*ptr

    > >
    > >
    > > *ptr++ means "Fetch the thing that `ptr' points to, and
    > > increment `ptr' so it points to the next thing."
    > >
    > > ++*ptr means "Increment the thing `ptr' points to, and
    > > leave `ptr' itself unchanged."
    > >

    >
    > The second expression is unambiguous even if you don't remember the
    > precedence rules or evaluation order. When it comes to the first
    > expression I'd increment ptr in a separate statement (even though most C
    > programmers love multiple side-effects).
    >
    > -- August


    Ok - Thank you for the answers

    Jason.S.
     
    Jason, May 15, 2005
    #4
  5. Jason

    CBFalconer Guest

    Eric Sosman wrote:
    > Jason wrote:
    >>
    >> could someone explain the difference to me inbetween:
    >> *ptr++ and ++*ptr

    >
    > *ptr++ means "Fetch the thing that `ptr' points to, and
    > increment `ptr' so it points to the next thing."
    >
    > ++*ptr means "Increment the thing `ptr' points to, and
    > leave `ptr' itself unchanged."


    and ++*ptr also fetches the incremented value pointed at.

    --
    Some informative links:
    news:news.announce.newusers
    http://www.geocities.com/nnqweb/
    http://www.catb.org/~esr/faqs/smart-questions.html
    http://www.caliburn.nl/topposting.html
    http://www.netmeister.org/news/learn2quote.html
     
    CBFalconer, May 15, 2005
    #5
  6. Jason

    Ben Pfaff Guest

    August Karlstrom <> writes:

    >> Jason wrote:
    >>
    >>> could someone explain the difference to me inbetween:
    >>> *ptr++ and ++*ptr

    >
    > The second expression is unambiguous even if you don't remember the
    > precedence rules or evaluation order. When it comes to the first
    > expression I'd increment ptr in a separate statement (even though most
    > C programmers love multiple side-effects).


    Each of *ptr++ and ++*ptr has only a single side effect.
    --
    Ben Pfaff
    email:
    web: http://benpfaff.org
     
    Ben Pfaff, May 16, 2005
    #6
  7. Jason

    Chris Dollin Guest

    August Karlstrom wrote:

    > Eric Sosman wrote:
    >> Jason wrote:
    >>
    >>> Hello,
    >>>
    >>> could someone explain the difference to me inbetween:
    >>> *ptr++ and ++*ptr

    >>
    >>
    >> *ptr++ means "Fetch the thing that `ptr' points to, and
    >> increment `ptr' so it points to the next thing."
    >>
    >> ++*ptr means "Increment the thing `ptr' points to, and
    >> leave `ptr' itself unchanged."
    >>

    >
    > The second expression is unambiguous even if you don't remember the
    > precedence rules or evaluation order. When it comes to the first
    > expression I'd increment ptr in a separate statement (even though most C
    > programmers love multiple side-effects).


    `*ptr++` is the standard C idiom for fetch-and-advance-pointer.
    Incrementing in a separate statement is likely to make the code more
    confusing, I'd have thought.

    --
    Chris "electric hedgehog" Dollin
    "The compiler is free to insert padding because it makes the struct
    look bigger and scares away predators." [Keith Thompson, comp.lang.c]
     
    Chris Dollin, May 16, 2005
    #7
  8. Jason

    pete Guest

    August Karlstrom wrote:
    >
    > Eric Sosman wrote:
    > > Jason wrote:
    > >
    > >> Hello,
    > >>
    > >> could someone explain the difference to me inbetween:
    > >> *ptr++ and ++*ptr

    > >
    > >
    > > *ptr++ means "Fetch the thing that `ptr' points to, and
    > > increment `ptr' so it points to the next thing."
    > >
    > > ++*ptr means "Increment the thing `ptr' points to, and
    > > leave `ptr' itself unchanged."
    > >

    >
    > The second expression is unambiguous even if you don't remember the
    > precedence rules or evaluation order.


    There is no evaluation order.
    Assignment is not a sequence point.

    This expression
    *ptr++
    has a value and a side effect.
    The side effect is that ptr is incremented.
    The value of the expression is the value of what ptr points to,
    prior to being incremented,
    but that evaluation can be made before
    or after the side effect takes place.

    --
    pete
     
    pete, May 16, 2005
    #8
  9. Ben Pfaff wrote:
    > Each of *ptr++ and ++*ptr has only a single side effect.


    Correct. When `*ptr++' (as well as `++*ptr') is part of a statement
    (with assignment, procedure calls etc.) though, it (the statement) will
    most likely have multiple side effects. The expression `*ptr++' as
    opposed to `++*ptr' doesn't make sense as a single statement (why would
    you want to dereference the pointer if you don't use it).

    -- August
     
    August Karlstrom, May 16, 2005
    #9
  10. Chris Dollin wrote:
    > `*ptr++` is the standard C idiom for fetch-and-advance-pointer.
    > Incrementing in a separate statement is likely to make the code more
    > confusing, I'd have thought.


    Confusing for the programmer who only has experience with C/C++, maybe.
    In almost any other language (procedural at the statement level) the
    incrementation is a separate statement.

    -- August
     
    August Karlstrom, May 16, 2005
    #10
  11. On Mon, 16 May 2005 14:55:53 GMT, August Karlstrom
    <> wrote:

    > Chris Dollin wrote:
    >> `*ptr++` is the standard C idiom for fetch-and-advance-pointer.
    >> Incrementing in a separate statement is likely to make the code more
    >> confusing, I'd have thought.

    >
    > Confusing for the programmer who only has experience with C/C++, maybe.
    > In almost any other language (procedural at the statement level) the
    > incrementation is a separate statement.


    Wenn mann in Deutsch sprache, es machts nicht das in Englisch verstanden
    Sie es nicht.

    Quand on parle en Francais, ce ne fait rein qeu les les idiomes ne sont
    pas les idiomes d'Anglais.

    If one is writing in C one should use C idiom, not Fortran idiom or Ada
    idiom. The C idiom is x = *ptr++, it doesn't matter that in COBOL I'd
    write something like MOVE X FROM ARRAY INDEXED BY I. ADD 1 TO I. Or
    that in assembler I'd write:

    mov bx, i[bp]
    mov x, [bx]
    inc i[bp]

    [Note: my German and French knowledge are about the same level as my
    Fortran and COBOL by this time, which is the point. If I were writing
    Fortran/speaking German primarily then I would probably have problems
    understanding C/English idiom; if I write C/speak English primarily then
    I have no problem with C/English idiom but do with that of other
    languages...]

    (And I have as little memory of whether 'idiomes' is correct French as
    whether MOVE is correct COBOL...)

    Chris C
     
    Chris Croughton, May 16, 2005
    #11
  12. Jason

    Ben Pfaff Guest

    August Karlstrom <> writes:

    > Ben Pfaff wrote:
    > > Each of *ptr++ and ++*ptr has only a single side effect.

    >
    > Correct. When `*ptr++' (as well as `++*ptr') is part of a statement
    > (with assignment, procedure calls etc.) though, it (the statement)
    > will most likely have multiple side effects. The expression `*ptr++'
    > as opposed to `++*ptr' doesn't make sense as a single statement (why
    > would you want to dereference the pointer if you don't use it).


    In my experience these kinds of expressions are often used as
    parts of `if' or `switch' conditionals that most often have only
    a single side effect (if any). Sometimes, yes, they are part of,
    e.g., assignments that will then have multiple side effects.
    --
    int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    );}return 0;}
     
    Ben Pfaff, May 17, 2005
    #12
  13. Chris Croughton wrote:
    > On Mon, 16 May 2005 14:55:53 GMT, August Karlstrom
    > <> wrote:
    >
    >
    >>Chris Dollin wrote:
    >>
    >>>`*ptr++` is the standard C idiom for fetch-and-advance-pointer.
    >>>Incrementing in a separate statement is likely to make the code more
    >>>confusing, I'd have thought.

    >>
    >>Confusing for the programmer who only has experience with C/C++, maybe.
    >>In almost any other language (procedural at the statement level) the
    >>incrementation is a separate statement.

    >
    >
    > Wenn mann in Deutsch sprache, es machts nicht das in Englisch verstanden
    > Sie es nicht.
    >
    > Quand on parle en Francais, ce ne fait rein qeu les les idiomes ne sont
    > pas les idiomes d'Anglais.
    >
    > If one is writing in C one should use C idiom, not Fortran idiom or Ada
    > idiom. The C idiom is x = *ptr++, it doesn't matter that in COBOL I'd
    > write something like MOVE X FROM ARRAY INDEXED BY I. ADD 1 TO I. Or
    > that in assembler I'd write:
    >
    > mov bx, i[bp]
    > mov x, [bx]
    > inc i[bp]
    >
    > [Note: my German and French knowledge are about the same level as my
    > Fortran and COBOL by this time, which is the point. If I were writing
    > Fortran/speaking German primarily then I would probably have problems
    > understanding C/English idiom; if I write C/speak English primarily then
    > I have no problem with C/English idiom but do with that of other
    > languages...]
    >
    > (And I have as little memory of whether 'idiomes' is correct French as
    > whether MOVE is correct COBOL...)


    Sure there are idioms in C, but the language is not exactly known for
    putting the programmer into a straitjacket. It allows you to do pretty
    much what you want. With the preprocessor you can even define a new
    language ;-)

    -- August
     
    August Karlstrom, May 17, 2005
    #13
  14. Jason

    Chris Dollin Guest

    August Karlstrom wrote:

    > Chris Dollin wrote:
    >> `*ptr++` is the standard C idiom for fetch-and-advance-pointer.
    >> Incrementing in a separate statement is likely to make the code more
    >> confusing, I'd have thought.

    >
    > Confusing for the programmer who only has experience with C/C++, maybe.


    No; confusing for the C programmer reading C code.

    > In almost any other language (procedural at the statement level) the
    > incrementation is a separate statement.


    In almost any other language, there are different idioms. One uses
    the idioms of the language one is using to the extent one can. If
    one deliberately avoids the usual idioms, one had better have a
    better reason for it than "but I can't do it that way in Prolog [1]!".

    [1] Clearly, since Prolog starts with a capital letter (P for Paris),
    it's a variable, and can be replaced by any value that makes the
    statement true. No?

    --
    Chris "doesn't use ++ for increment in stand-alone expressions" Dollin
    "The compiler is free to insert padding because it makes the struct
    look bigger and scares away predators." [Keith Thompson, comp.lang.c]
     
    Chris Dollin, May 17, 2005
    #14
  15. On Tue, 17 May 2005 02:03:37 GMT, August Karlstrom
    <> wrote:

    > Chris Croughton wrote:
    >> On Mon, 16 May 2005 14:55:53 GMT, August Karlstrom
    >> <> wrote:
    >>
    >>>Chris Dollin wrote:
    >>>
    >>>>`*ptr++` is the standard C idiom for fetch-and-advance-pointer.
    >>>>Incrementing in a separate statement is likely to make the code more
    >>>>confusing, I'd have thought.
    >>>
    >>>Confusing for the programmer who only has experience with C/C++, maybe.
    >>>In almost any other language (procedural at the statement level) the
    >>>incrementation is a separate statement.

    >>
    >> If one is writing in C one should use C idiom, not Fortran idiom or Ada
    >> idiom. The C idiom is x = *ptr++, it doesn't matter that in COBOL I'd
    >> write something like MOVE X FROM ARRAY INDEXED BY I. ADD 1 TO I. Or
    >> that in assembler I'd write:
    >>
    >> mov bx, i[bp]
    >> mov x, [bx]
    >> inc i[bp]

    >
    > Sure there are idioms in C, but the language is not exactly known for
    > putting the programmer into a straitjacket. It allows you to do pretty
    > much what you want. With the preprocessor you can even define a new
    > language ;-)


    You can indeed (see a thread recently (somewhen in the last several
    months, anyway) about someone doing just that), but anyone who finds
    *ptr++ confusing is no more a "C programmer" than I am a "French
    novelist". If you don't know the idioms then you don't know the
    language. You /can/ write ptr = ptr + 1; instead of ++ptr if you want
    (in some early compilers the forms ++i, i =+ 1 and i = i + 1 actually
    generated different code deliberately), but any C programmer should be
    equally at ease with any of them

    Having the increment separate often loses some of the readability of the
    language. Compare:

    *ptr++ = a;
    *ptr++ = b;
    *ptr-- = c;
    *ptr++ = d;

    with:

    *ptr = a;
    ++ptr;
    *ptr = b;
    ++ptr;
    *ptr = c;
    --ptr;
    *ptr = d;
    ++ptr;

    The former is obvious (to any C programmer), the latter is visually
    confusing and harder to maintain. Note "visually confusing", it's not
    confusing to a C or C++ programmer as a concept, it is confusing to the
    eye. There's a mistake in them which is visually obvious in the first
    but not in the second. Merging lines:

    *ptr = a; ++ptr;
    *ptr = b; ++ptr;
    *ptr = c; --ptr;
    *ptr = d; ++ptr;

    makes that mistake more obvious again, but makes maintenance messier
    when 'b' becomes 'fred' and you need to line up the others.

    Chris C
     
    Chris Croughton, May 17, 2005
    #15
  16. Chris Croughton wrote:
    > On Tue, 17 May 2005 02:03:37 GMT, August Karlstrom
    > <> wrote:
    >
    >
    >>Chris Croughton wrote:
    >>
    >>>On Mon, 16 May 2005 14:55:53 GMT, August Karlstrom
    >>> <> wrote:
    >>>
    >>>
    >>>>Chris Dollin wrote:
    >>>>
    >>>>
    >>>>>`*ptr++` is the standard C idiom for fetch-and-advance-pointer.
    >>>>>Incrementing in a separate statement is likely to make the code more
    >>>>>confusing, I'd have thought.
    >>>>
    >>>>Confusing for the programmer who only has experience with C/C++, maybe.
    >>>>In almost any other language (procedural at the statement level) the
    >>>>incrementation is a separate statement.
    >>>
    >>>If one is writing in C one should use C idiom, not Fortran idiom or Ada
    >>>idiom. The C idiom is x = *ptr++, it doesn't matter that in COBOL I'd
    >>>write something like MOVE X FROM ARRAY INDEXED BY I. ADD 1 TO I. Or
    >>>that in assembler I'd write:
    >>>
    >>> mov bx, i[bp]
    >>> mov x, [bx]
    >>> inc i[bp]

    >>
    >>Sure there are idioms in C, but the language is not exactly known for
    >>putting the programmer into a straitjacket. It allows you to do pretty
    >>much what you want. With the preprocessor you can even define a new
    >>language ;-)

    >
    >
    > You can indeed (see a thread recently (somewhen in the last several
    > months, anyway) about someone doing just that), but anyone who finds
    > *ptr++ confusing is no more a "C programmer" than I am a "French
    > novelist". If you don't know the idioms then you don't know the
    > language. You /can/ write ptr = ptr + 1; instead of ++ptr if you want
    > (in some early compilers the forms ++i, i =+ 1 and i = i + 1 actually
    > generated different code deliberately), but any C programmer should be
    > equally at ease with any of them
    >
    > Having the increment separate often loses some of the readability of the
    > language. Compare:
    >
    > *ptr++ = a;
    > *ptr++ = b;
    > *ptr-- = c;
    > *ptr++ = d;
    >
    > with:
    >
    > *ptr = a;
    > ++ptr;
    > *ptr = b;
    > ++ptr;
    > *ptr = c;
    > --ptr;
    > *ptr = d;
    > ++ptr;
    >
    > The former is obvious (to any C programmer), the latter is visually
    > confusing and harder to maintain. Note "visually confusing", it's not
    > confusing to a C or C++ programmer as a concept, it is confusing to the
    > eye. There's a mistake in them which is visually obvious in the first
    > but not in the second. Merging lines:
    >
    > *ptr = a; ++ptr;
    > *ptr = b; ++ptr;
    > *ptr = c; --ptr;
    > *ptr = d; ++ptr;
    >
    > makes that mistake more obvious again, but makes maintenance messier
    > when 'b' becomes 'fred' and you need to line up the others.


    There are various reasons why you want to or have to program in C.
    Expressions involving increment and decrement operators can get
    arbitrarily complex and the "cleverer" the programmer the harder it will
    be to maintain the code.

    The example above can be translated to

    ptr[0] = a;
    ptr[1] = b;
    ptr[2] = c;
    ptr[1] = d;
    ptr++;

    which clearly shows that the second statement is superfluous so the
    statement sequence can be rewritten as

    ptr[0] = a;
    ptr[1] = d;
    ptr[2] = c;
    ptr++;

    The compiler will then probably optimize the code to make it as fast as
    before. Which version do you think is more readable?

    Note that I have nothing against the increment/decrement operator if it
    is used in a single statement.


    -- August
     
    August Karlstrom, May 17, 2005
    #16
  17. Jason

    Michael Mair Guest

    August Karlstrom wrote:
    > Chris Croughton wrote:
    >
    >> On Tue, 17 May 2005 02:03:37 GMT, August Karlstrom
    >> <> wrote:
    >>
    >>> Chris Croughton wrote:
    >>>
    >>>> On Mon, 16 May 2005 14:55:53 GMT, August Karlstrom
    >>>> <> wrote:
    >>>>
    >>>>> Chris Dollin wrote:
    >>>>>
    >>>>>> `*ptr++` is the standard C idiom for fetch-and-advance-pointer.
    >>>>>> Incrementing in a separate statement is likely to make the code more
    >>>>>> confusing, I'd have thought.
    >>>>>
    >>>>> Confusing for the programmer who only has experience with C/C++,
    >>>>> maybe. In almost any other language (procedural at the statement
    >>>>> level) the incrementation is a separate statement.
    >>>>
    >>>> If one is writing in C one should use C idiom, not Fortran idiom or Ada
    >>>> idiom. The C idiom is x = *ptr++, it doesn't matter that in COBOL I'd
    >>>> write something like MOVE X FROM ARRAY INDEXED BY I. ADD 1 TO I. Or
    >>>> that in assembler I'd write:
    >>>>
    >>>> mov bx, i[bp]
    >>>> mov x, [bx]
    >>>> inc i[bp]
    >>>
    >>> Sure there are idioms in C, but the language is not exactly known for
    >>> putting the programmer into a straitjacket. It allows you to do
    >>> pretty much what you want. With the preprocessor you can even define
    >>> a new language ;-)

    >>
    >> You can indeed (see a thread recently (somewhen in the last several
    >> months, anyway) about someone doing just that), but anyone who finds
    >> *ptr++ confusing is no more a "C programmer" than I am a "French
    >> novelist". If you don't know the idioms then you don't know the
    >> language. You /can/ write ptr = ptr + 1; instead of ++ptr if you want
    >> (in some early compilers the forms ++i, i =+ 1 and i = i + 1 actually
    >> generated different code deliberately), but any C programmer should be
    >> equally at ease with any of them
    >>
    >> Having the increment separate often loses some of the readability of the
    >> language. Compare:
    >>
    >> *ptr++ = a;
    >> *ptr++ = b;
    >> *ptr-- = c;
    >> *ptr++ = d;
    >>
    >> with:
    >>
    >> *ptr = a;
    >> ++ptr;
    >> *ptr = b;
    >> ++ptr;
    >> *ptr = c;
    >> --ptr;
    >> *ptr = d;
    >> ++ptr;
    >>
    >> The former is obvious (to any C programmer), the latter is visually
    >> confusing and harder to maintain. Note "visually confusing", it's not
    >> confusing to a C or C++ programmer as a concept, it is confusing to the
    >> eye. There's a mistake in them which is visually obvious in the first
    >> but not in the second. Merging lines:
    >>
    >> *ptr = a; ++ptr;
    >> *ptr = b; ++ptr;
    >> *ptr = c; --ptr;
    >> *ptr = d; ++ptr;
    >>
    >> makes that mistake more obvious again, but makes maintenance messier
    >> when 'b' becomes 'fred' and you need to line up the others.

    >
    > There are various reasons why you want to or have to program in C.
    > Expressions involving increment and decrement operators can get
    > arbitrarily complex and the "cleverer" the programmer the harder it will
    > be to maintain the code.


    Reminds me of
    "Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are, by
    definition, not smart enough to debug it."
    (attributed to B.W. Kernighan)
    :)

    > The example above can be translated to
    >
    > ptr[0] = a;
    > ptr[1] = b;
    > ptr[2] = c;
    > ptr[1] = d;
    > ptr++;
    >
    > which clearly shows that the second statement is superfluous so the
    > statement sequence can be rewritten as
    >
    > ptr[0] = a;
    > ptr[1] = d;
    > ptr[2] = c;
    > ptr++;


    At least as long as no "volatile" is hanging around for fun...


    > The compiler will then probably optimize the code to make it as fast as
    > before. Which version do you think is more readable?


    Honestly, for me both is the same.
    I use whatever expresses the way _I_ think about the task the
    code performs. As soon as I have to explain some sort of "cleverness"
    in more than half a line, I go for a more readable way of writing
    the code.


    > Note that I have nothing against the increment/decrement operator if it
    > is used in a single statement.


    This is in my case one of the rarer uses (apart from the increment part
    of for). In single statements, I do not need the side effect as a side
    effect but as "main effect", so I can as well express it by += 1.


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, May 17, 2005
    #17
  18. On Tue, 17 May 2005 20:11:46 GMT, August Karlstrom
    <> wrote:

    > Chris Croughton wrote:
    >>
    >> Having the increment separate often loses some of the readability of the
    >> language. Compare:
    >>
    >> *ptr++ = a;
    >> *ptr++ = b;
    >> *ptr-- = c;
    >> *ptr++ = d;
    >>
    >> with:
    >>
    >> *ptr = a;
    >> ++ptr;
    >> *ptr = b;
    >> ++ptr;
    >> *ptr = c;
    >> --ptr;
    >> *ptr = d;
    >> ++ptr;
    >>
    >> The former is obvious (to any C programmer), the latter is visually
    >> confusing and harder to maintain. Note "visually confusing", it's not
    >> confusing to a C or C++ programmer as a concept, it is confusing to the
    >> eye. There's a mistake in them which is visually obvious in the first
    >> but not in the second. Merging lines:
    >>
    >> *ptr = a; ++ptr;
    >> *ptr = b; ++ptr;
    >> *ptr = c; --ptr;
    >> *ptr = d; ++ptr;
    >>
    >> makes that mistake more obvious again, but makes maintenance messier
    >> when 'b' becomes 'fred' and you need to line up the others.

    >
    > There are various reasons why you want to or have to program in C.
    > Expressions involving increment and decrement operators can get
    > arbitrarily complex and the "cleverer" the programmer the harder it will
    > be to maintain the code.


    So ban all complex expressions, just like MS Word tries to do with
    complex sentences. "C program." "C program run." "Run, program, run!"
    "I said run, dammit, not crash the OS!"

    > The example above can be translated to
    >
    > ptr[0] = a;
    > ptr[1] = b;
    > ptr[2] = c;
    > ptr[1] = d;
    > ptr++;


    Wrong: in the example ptr is incremented three times and decremented
    once, so it should be ptr += 2;

    But anyway, I said that there was a mistake: the -- should have been a
    ++ which was what was 'obvious' when looking at the first version (why
    was one of them different?). Indeed, I said that it was a mistake
    several times. And it's something which is not as obvious with the
    increment on a different line.

    But your 'translation' is not necessarily the same anyway. Some of the
    *ptr++ = whatever statements might be conditional so absolute offsets
    aren't applicable.

    Make each of them conditional:

    if (a) *ptr++ = a;
    if (b) *ptr++ = b;
    if (c) *ptr-- = c;
    if (d) *ptr++ = d;

    And you can no longer do your 'translation'.

    > which clearly shows that the second statement is superfluous


    But what it misses is that the second one is /wrong/.
     
    Chris Croughton, May 18, 2005
    #18
  19. Chris Croughton wrote:
    > On Tue, 17 May 2005 20:11:46 GMT, August Karlstrom
    > <> wrote:
    >
    >
    >>Chris Croughton wrote:
    >>
    >>>Having the increment separate often loses some of the readability of the
    >>>language. Compare:
    >>>
    >>> *ptr++ = a;
    >>> *ptr++ = b;
    >>> *ptr-- = c;
    >>> *ptr++ = d;
    >>>
    >>>with:
    >>>
    >>> *ptr = a;
    >>> ++ptr;
    >>> *ptr = b;
    >>> ++ptr;
    >>> *ptr = c;
    >>> --ptr;
    >>> *ptr = d;
    >>> ++ptr;
    >>>
    >>>The former is obvious (to any C programmer), the latter is visually
    >>>confusing and harder to maintain. Note "visually confusing", it's not
    >>>confusing to a C or C++ programmer as a concept, it is confusing to the
    >>>eye. There's a mistake in them which is visually obvious in the first
    >>>but not in the second. Merging lines:
    >>>
    >>> *ptr = a; ++ptr;
    >>> *ptr = b; ++ptr;
    >>> *ptr = c; --ptr;
    >>> *ptr = d; ++ptr;
    >>>
    >>>makes that mistake more obvious again, but makes maintenance messier
    >>>when 'b' becomes 'fred' and you need to line up the others.

    >>
    >>There are various reasons why you want to or have to program in C.
    >>Expressions involving increment and decrement operators can get
    >>arbitrarily complex and the "cleverer" the programmer the harder it will
    >>be to maintain the code.

    >
    >
    > So ban all complex expressions, just like MS Word tries to do with
    > complex sentences. "C program." "C program run." "Run, program, run!"
    > "I said run, dammit, not crash the OS!"
    >
    >
    >>The example above can be translated to
    >>
    >>ptr[0] = a;
    >>ptr[1] = b;
    >>ptr[2] = c;
    >>ptr[1] = d;
    >>ptr++;

    >
    >
    > Wrong: in the example ptr is incremented three times and decremented
    > once, so it should be ptr += 2;
    >
    > But anyway, I said that there was a mistake: the -- should have been a
    > ++ which was what was 'obvious' when looking at the first version (why
    > was one of them different?). Indeed, I said that it was a mistake
    > several times. And it's something which is not as obvious with the
    > increment on a different line.
    >
    > But your 'translation' is not necessarily the same anyway. Some of the
    > *ptr++ = whatever statements might be conditional so absolute offsets
    > aren't applicable.
    >
    > Make each of them conditional:
    >
    > if (a) *ptr++ = a;
    > if (b) *ptr++ = b;
    > if (c) *ptr-- = c;
    > if (d) *ptr++ = d;
    >
    > And you can no longer do your 'translation'.
    >
    >
    >>which clearly shows that the second statement is superfluous

    >
    >
    > But what it misses is that the second one is /wrong/.
    >
    >


    Sorry, I missed the deliberate nature of the bug in your example.

    If your latest example was written as

    int i, tests[4] = {a, b, c, d};

    for (i = 0; i < 4; i++) if (tests) ptr = tests;
    /* Use the value of i instead of incrementing `ptr'. */

    in the first place there would be no such bug. Okay, the above is
    slightly less efficient, but probably it won't matter, it all depends on
    the situation. See the answers to the clc posting "wrinting an optimised
    code" by junky_fellow 17 of May.

    -- August
     
    August Karlstrom, May 19, 2005
    #19
  20. Jason

    Chris Torek Guest

    >Chris Croughton wrote:
    >> if (a) *ptr++ = a;
    >> if (b) *ptr++ = b;
    >> if (c) *ptr-- = c;
    >> if (d) *ptr++ = d;


    (where "*ptr--" is a bug because it should read "*ptr++")

    In article <Uh1je.24734$>
    August Karlstrom <> wrote:
    >Sorry, I missed the deliberate nature of the bug in your example.
    >
    >If your latest example was written as
    >
    > int i, tests[4] = {a, b, c, d};
    >
    > for (i = 0; i < 4; i++) if (tests) ptr = tests;
    > /* Use the value of i instead of incrementing `ptr'. */
    >
    >in the first place there would be no such bug. Okay, the above is
    >slightly less efficient, but probably it won't matter ...


    It produces a different result, which probably *does* matter. :)

    The sample code "compresses out zeros" (once one fixes the *ptr--).
    The rewrite does not compress out zeros, instead leaving ptr
    unchanged when tests==0.

    A correct array rewrite of the corrected code might read:

    for (i = j = 0; i < 4; i++)
    if (tests != 0)
    ptr[j++] = tests;

    though of course this leaves "ptr" unchanged. (If we want ptr to
    advance, just add "ptr += j" after the loop -- or just change the
    loop to write on *ptr++ in the first place, eliminating j entirely.)

    The important thing, in all of this, is really that "*ptr++" is a
    pretty common idiom in C, so one should get to know it if one is
    to do much C programming. The sequence "*p++ = val" "means" "update
    the array element to which p points, and also update p to point to
    the next array element", while "x = *p++" "means" "fetch the array
    element to which p points, and also update p to point to the next
    array element". Of course, it also becomes important to understand
    sequence points, because the "updating" happens "between the previous
    and next sequence point", and variables that will be updated must
    be left alone (for their new values to settle in) until that next
    sequence point has occurred.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, May 19, 2005
    #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. jakk
    Replies:
    4
    Views:
    12,218
  2. Sid
    Replies:
    5
    Views:
    1,077
  3. hans christian

    newbie question: difference between (*ptr) and *ptr

    hans christian, Jun 11, 2006, in forum: C Programming
    Replies:
    5
    Views:
    733
    hans christian
    Jun 11, 2006
  4. AY
    Replies:
    4
    Views:
    2,198
  5. Nick Keighley
    Replies:
    0
    Views:
    513
    Nick Keighley
    Jul 28, 2009
Loading...

Share This Page