C/C++ Post-increment by more than one

17,418

Solution 1

Well, I did answer my question in the edit... Basically what I wanted was a single expression which evaluates to the original value but has a side effect of incrementing by an arbitrary amount. Here are some macros.

#define INC(x,inc) (((x)+=(inc))-(inc))
#define INC2(x) INC(x,2)
#define INC4(x) INC(x,4)
#define INC8(x) INC(x,8)

Solution 2

how can I post-increment position by 2 or 4?

You can't post-increment a variable by 2 or 4 but you can use the following (in your case)

read_ptr(buffer+position); position += 2;

Solution 3

Although, I would not recommend this solution, but if you don't want to change this line in your code:

read_ptr(buffer+(position++));

And you still want to post-increment position by 2, then define position as Index position(2); where the type Index is defined here, and also shown the usage:

struct Index
{
    int step;
    int value;
    Index(int s=1, int v=0): step(s), value(v) {}
    Index operator++(int) 
    { 
       Index prev(step, value); 
       value += step; 
       return prev;
    }
    operator int() { return value; }
};

int main() {
        char arr[] = "1234567890" ;

        cout <<"Increment by 2" <<endl;
        Index i2(2); //increment by 2
        cout << *(arr + (i2++)) << endl;
        cout << *(arr + (i2++)) << endl;
        cout << *(arr + (i2++)) << endl;
        cout << *(arr + (i2++)) << endl;

        cout <<"Increment by 3" <<endl;        
        Index i3(3); //increment by 3
        cout << *(arr + (i3++)) << endl;
        cout << *(arr + (i3++)) << endl;
        cout << *(arr + (i3++)) << endl;
        cout << *(arr + (i3++)) << endl;
        return 0;
}

Output:

Increment by 2
1
3
5
7
Increment by 3
1
4
7
0

Working Example : http://ideone.com/CFgal

Note: I would still not suggest this solution in real life project. It's more like puzzle :D

Solution 4

You don't; you break it up into more than one line. There is no reason to stuff everything into one line here.

read_ptr( buffer + position );
position += n;

Solution 5

The += operator would be a separate statement (not post or pre increment). You could use the following line:

func(buffer + position); position += 2;
Share:
17,418

Related videos on Youtube

Steven Lu
Author by

Steven Lu

Play a multitouch HTML5 Tetris clone -- http://htmltetris.com (Interesting note about this site. It used to be my site, then Tetris Co. sent me a cease and desist, then I forgot about it, and now it’s back: someone brought it back and put MY code back on the site.) A huge fan of tmux and vim.

Updated on May 25, 2022

Comments

  • Steven Lu
    Steven Lu almost 2 years

    I'm reading bytes from a buffer. But sometimes what I'm reading is a word or longer.

    // assume buffer is of type unsigned char *
    read_ptr(buffer+(position++))
    

    That's fine but how can I post-increment position by 2 or 4? There's no way I can get the += operator to post-increment, is there?

    Reason is, I have this big awful expression which I want to evaluate, while at the same time incrementing the position variable.

    I think I came up with my own solution. I'm pretty sure it works. Everyone's gonna hate it though, since this isn't very readable code.

    read_ptr(buffer+(position+=4)-4)
    

    I will then make this into a macro after testing it a bit to make sure it's doing the right thing.

    IN CONCLUSION:

    Don't do this. It's just a bad idea because this is the sort of thing that generates unmaintainable code. But... it does turn out to be quite easy to convert any pre-incrementing operator into a post-incrementing one.

    • Martin York
      Martin York about 13 years
      Don't do that. Write the code to be clear and easy to read. Abusing the operators like that will only make you cry when the application blows up.
    • tJener
      tJener
      Note that incrementing a pointer doesn't not necessarily mean that the new value for the pointer is a 1 byte difference.
    • paxdiablo
      paxdiablo
      And, more importantly, it will make us cry if we ever have to maintain that monstrosity. You should always assume that the guy who inherits your code is a psychopath who knows where you live :-)
  • cHao
    cHao about 13 years
    "Post-increment" implies the two lines should be switched.
  • Nawaz
    Nawaz about 13 years
    That is not post-increment, Prasoon!
  • paxdiablo
    paxdiablo about 13 years
    And that becomes so much better (as in, we don't need to go to the standard to check if order is guaranteed) if you just replace that , with a ;. I know, it's a few more electrons on your monitor or ink on your paper, but isn't that worth it for the readability? :-)
  • Prasoon Saurav
    Prasoon Saurav about 13 years
    @paxdiablo : But the effect would be same, isn't it? However as you mentioned as far as readability is concerned ; is much better.
  • paxdiablo
    paxdiablo about 13 years
    @Prasoon, that "isn't it?" is the problem. I would have to go look up the standard to see if , was a sequence point, guaranteeing order. I know that ; will guarantee it, , may guarantee it but my years are too advanced for me to worry about it unnecessarily :-) But, since you changed it, +1.
  • Steven Lu
    Steven Lu about 13 years
    Wow. Now this is taking it to another level. It's definitely more readable than my solution I came up with...
  • Steven Lu
    Steven Lu about 13 years
    Yes, I think an alternate way to achieve what I wanted (kind of) is to increment the pointer itself, as long as it is the appropriate type. Then the ++ operator may be used.
  • Nawaz
    Nawaz about 13 years
    @Steven: If it's puzzle or playing around with C++, then you can do such gymnastic. But don't do that in real project!
  • Steven Lu
    Steven Lu about 13 years
    indeed. Is there a way to have a parameterizable postincrement operator though? Like, redefine the += operator to get it to post- rather than pre-increment by whatever the right operand is.
  • Nawaz
    Nawaz about 13 years
    @Steven: Yes. You can overload operator+ also.
  • Steve Jessop
    Steve Jessop about 13 years
    "I would have to go look up the standard to see if , was a sequence point" - so the question is whether we're coding for maintenance programmers who know what the comma operator does, or maintenance programmers who don't. This is a general problem in C++, I think, "what can we assume about the competence of: (a) typical, (b) worst-likely-case, programmers. The most obvious answer, "they know the same as me", is wrong, and the second-most obvious, "they know nothing" is too limiting given the power of C++ to do clever but slightly-obscure things.
  • Steve Jessop
    Steve Jessop about 13 years
    Of course in this case there's no advantage of a comma over a semi-colon, since we're not in a context where we need to write a single expression. Which is probably why people have to look up what the comma-operator means - it's so rarely appropriate that people aren't familiar with it. Again because C++ is full of obscure cleverness.
  • Steven Lu
    Steven Lu over 11 years
    The reason to stuff everything into one line is if it is used as an expression rather than just a statement.
  • Ed S.
    Ed S. over 11 years
    @StevenLuL Except that's not a real requirement. There is no reason you need to shove this all into one line and, if you do, you'll be worse off for it.