chipKIT® Development Platform

Inspired by Arduino™

*Pointer++ cpp interpretation

Created Tue, 09 Feb 2016 17:55:59 +0000 by FredCailloux


FredCailloux

Tue, 09 Feb 2016 17:55:59 +0000

In the example pmodJSTK.cpp is defined an array recv[5] of type unsigned integer 8 bits as such: uint8_t recv[5]; Can you please confirm the following assumption:

uint8_t * myPointer ;
 myPointer = &recv[0] ;
 myPointer = myPointer + 1 ;
 *myPointer = spiCon.tranfer(ledSt) ;

Above is equivalent to below ( from the pmodJSTK example cpp code)

*recv++ = spiCon.transfer(ledSt);

I am not sure exactly how the compiler will interpret the *recv++ ? Here is my interpretation of this code: *recv is pointing to the first item, array recv[0]. *recv++ is pointing to second item, array recv[1] Hence, recv[1] will endup taking the result of the function call spiCon.transfer(ledSt) Is that what happen ? Appreciate your input.


majenko

Tue, 09 Feb 2016 18:54:54 +0000

This might be of some help to you:

http://en.cppreference.com/w/cpp/language/operator_precedence

The recv++ is of a higher precedence than the *recv, so the recv++ go together as a unit and the * is then secondary. It's exactly the same as if you had the brackets:

*(recv++)

And since the ++ is after the recv it's a post-increment, so it gets incremented after the assignment happens. So in long-hand it's:

*recv = spiCon.transfer(ledSt);
recv++;

But you don't want to do that to a defined array because it would cripple the array. You should only ever do it to a pointer to an array, so:

uint8_t *myPointer = recv;
*myPointer++ = spiCon.transfer(ledSt);

Note that recv and &recv[0] are the same - they are both pointers to the start of the array.

If you were to increment recv then recv[0] would actually be pointing to recv[1], which would be very bad.


FredCailloux

Tue, 09 Feb 2016 21:51:52 +0000

Thanks for the cppreference.com - it appears to be very well presented. I sure will bookmark this site. You sure did clarified a few concepts here but you also got me confused. There is something here that appear to me as contradictory. Can you please clarify. First you mention that

*recv++  // is equivalent to 
*(recv++)

Fine, I can see that from the precedence table. Then you indicate that the ++ is post-increment, hence, the line

*recv++ = spiCon.transfer(ledSt);   //  would be equivalent to 
*recv = spiCon.transfer(ledSt);     
recv++;

So, my confusion is if recv++ as precedence doesn't it mean that it will be incremented Before the dereference* operator ? If so, the final result would be that recv[1] would take the function value, not recv[0] What am I missing ?


majenko

Tue, 09 Feb 2016 23:13:13 +0000

What you're missing is that the "post" doesn't apply to the single operator, but to the whole of the assignment.

If it were:

*++foo = blahblah;

then foo would be incremented before the assignment, not after.

For instance, this little bit of code (for a PC not a chipKIT):

#include <stdio.h>

int foo[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

int main() {
    int i;
    int *foo2 = foo;
    *foo2++ = 23;

    for (i = 0; i < 10; i++) {
        printf("%d: %d\n", i, foo[i]);
    }
}

results in:

0: 23
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9

As you can see the assignment happened before the increment. Similarly this bit of code:

#include <stdio.h>

int main() {
    int foo = 0;
    int bar = foo++;
    printf("foo = %d bar = %d\n", foo, bar);
    return 0;
}

results in:

foo = 1 bar = 0

because the increment of foo happens post the assignment of its value to bar.


FredCailloux

Wed, 10 Feb 2016 16:13:00 +0000

I got it! I must admit, pointer stuff is not very "Reader Friendly" but hey! who am I to comment 33 years of C++ refinements. Thanks a lot Majenko. By the way, is there something you don't know about C++ programming ? :) Joke :)


majenko

Wed, 10 Feb 2016 17:10:23 +0000

I don't know, but I do know there are things that I don't know about C++ programming ;)

Have you ever looked at C++ templates? They're "fun"! ;)