PIC24 & Pointers:  Value pointed at increments by 5 instead of 1? - Page 1
Forum section: electronics / beginners

author: smoothVTer
author_rank: Regular Contributor
timestamp: March 28, 2017, 03:46:37 pm
content: I have a simple function that takes a pointer to a variable & increments the value stored at the variable's address.Using MPLAB X as my IDE on a PIC24FJ256 device.Code://******** main.c *********//// Declared these globally so MPLABX debugger can see ituint8_t testCount;uint8_t *testCount_p = &testCount;void incrCount( uint8_t *counter ){*counter += 1; // This line increments by 5 instead of 1//*counter++; // This line increments by 5 instead of 1//(*counter) += 1; // This line increments by 3 instead of 1}void main ( void ){testCount = 0x00; // Initialize the count to = 0incrCount( testCount_p );// At this point, testCount = 0x05 ???}I am not sure why, when I dereference & increment the local pointer inside incrCount, the global variable testCount is incremented by 5? If I enclose the increment operation in parentheses like this:Code://(*counter) += 1; // This line increments by 3 instead of 1testCount is incremented by3each time.Does anybody here have an idea of why this is so? I'm expecting the global variable testCount to increment by 1 each time incrCount() is called, but getting increments of 5 and 3 instead.

author: Octane
author_rank: Regular Contributor
timestamp: March 29, 2017, 06:01:41 pm
content: I did pointer stuff some time ago already, so maybe my memory is tricking me, but shouldn't it be:uint8_t * testCount_p = &testCount;Mind the space between * and testCount_p.May be totally wrong though...

author: danadak
author_rank: Super Contributor
timestamp: March 29, 2017, 10:46:35 pm
content: When you do this in main()incrCount( testCount_p );You are passing to the function the value of testCount_p, not its addressas specified by the definition of incrCount().Should not the call be typed as -incrCount( &testCount_p );Regards, Dana.

author: gnif
author_rank: Unknown
timestamp: March 29, 2017, 10:53:55 pm
content: Your code looks correct...Quote from: danadak on March 29, 2017, 10:46:35 pmIncorrect, you would then be passing a pointer to a pointer... testCount_p is already a pointer to the target address.Quote from: Octane on March 29, 2017, 06:01:41 pmIncorrect, the spacing around the * is inconsequential. C does not care at all for white space, you can write your entire application without spaces or new lines if you like.It seems odd, I would suggest you compile it with GCC or similar as a x86 program, just as a test to ensure there isn't something funny going on. Outside of this I would say it's a compiler problem.

author: Octane
author_rank: Regular Contributor
timestamp: March 29, 2017, 11:36:34 pm
content: Quote from: gnif on March 29, 2017, 10:53:55 pmReally? You don't need a space between the type keyword and the variable name?So,inttest;orunsignedinttest;works?

author: IanB
author_rank: Super Contributor
timestamp: March 29, 2017, 11:43:32 pm
content: Quote from: Octane on March 29, 2017, 11:36:34 pmNot quite, but all of the following are equivalent:Code:int *p;int* p;int*p;int * p;The lexer will see four items, "int", "*", "p" and ";" and the compiler will process them accordingly.

author: danadak
author_rank: Super Contributor
timestamp: March 29, 2017, 11:46:33 pm
content: Thanks Octane, I thought I was passing testCount, not testCount_pThis seems to work under GNU, I check at end of main for testCount = 2, and it does.Code:// Declared these globally so MPLABX debugger can see ituint8_t testCount;uint8_t *testCount_p = &testCount;uint8 myvar;void incrCount( uint8_t *counter ){*counter += 1; // This line increments by 5 instead of 1//*counter++; // This line increments by 5 instead of 1//(*counter) += 1; // This line increments by 3 instead of 1}int main ( void ){testCount = 0x00; // Initialize the count to = 0incrCount( testCount_p );incrCount( testCount_p );// At this point, testCount = 0x05 ???}

author: gnif
author_rank: Unknown
timestamp: March 29, 2017, 11:56:14 pm
content: Quote from: Octane on March 29, 2017, 11:36:34 pmAha, sorry yeah, spaces are not needed around operationals, etc. I should have been more clear.Since it works under GCC, and it seems there is no logical issue with your code, I would say that there is an issue with either the debugger or compiler. Perhaps find some other way to check the value of testCount, such as flash a LED, this would confirm if it is a debugger or compiler bug.

author: Octane
author_rank: Regular Contributor
timestamp: March 30, 2017, 12:06:50 am
content: Quote from: IanB on March 29, 2017, 11:43:32 pmYes, i can believe that. I just was confused that gnif stated you don't needanywhitespaces.As I said, quite one time that I used pointers last, but that should change now again, since I'm getting my lab the next few weeks.

author: StillTrying
author_rank: Super Contributor
timestamp: March 30, 2017, 12:08:01 am
content: uint8_t *testCount_p = &testCount;Is 8 bits enough for the pointer.

author: Octane
author_rank: Regular Contributor
timestamp: March 30, 2017, 12:10:25 am
content: Quote from: danadak on March 29, 2017, 11:46:33 pmWhat was the solution now? In your original code you passed testCount_p, no?please ignore: misread a post...

author: Octane
author_rank: Regular Contributor
timestamp: March 30, 2017, 12:13:14 am
content: Quote from: gnif on March 29, 2017, 11:56:14 pmNo worries, it just threw me off...

author: Octane
author_rank: Regular Contributor
timestamp: March 30, 2017, 12:15:32 am
content: smoothVTer, is this all the code, or did you cut it down?

author: StillTrying
author_rank: Super Contributor
timestamp: March 30, 2017, 12:36:36 am
content: Quote from: evb149 on March 30, 2017, 12:11:57 amuint8_t *testCount_p= &testCount;I still think it's a problem. (but I'm quite rusty!)

author: gnif
author_rank: Unknown
timestamp: March 30, 2017, 12:40:24 am
content: Quote from: StillTrying on March 30, 2017, 12:36:36 amNot at all, this is completely correct.uint8_t * = a pointer to a value that contains a uint8_t value. The pointer size is determined by the architecture and the compiler knows it.&testCount = the address of testCount.The fact that it works under GNU C just fine shows that it is not a code issue, this is standard C stuff, the issue is with the build/compiler or debugger. It could be that the init code is doing things wrong.@danadak, try using incrCount(&testCount) instead, if this works correctly it is clear that the init code isn't initializing the variable properly before main is called.

author: StillTrying
author_rank: Super Contributor
timestamp: March 30, 2017, 01:26:39 am
content: Quote from: gnif on March 30, 2017, 12:40:24 amYep, works with char in windoze, so you and evb149 are correct!

author: mib
author_rank: Contributor
timestamp: March 30, 2017, 08:24:05 am
content: You never initialize testcount. That's the problem.Addtestcount = 0;To the start of main()

author: pyroesp
author_rank: Regular Contributor
timestamp: March 30, 2017, 09:10:34 am
content: Quote from: mib on March 30, 2017, 08:24:05 amCheck the code again, he did that.Code:// Declared these globally so MPLABX debugger can see ituint8_t testCount;//...int main ( void ){testCount = 0x00; // Initialize the count to = 0//...}Can you provide the compiled ASM file ?I find it curious that it increments more than once.How are you debugging this ? With the simulator or an ICD ?Also, I've always finished my microcontroller code with an infinite loop or put everything inside a "main loop", maybe try adding one.

author: danadak
author_rank: Super Contributor
timestamp: March 30, 2017, 10:13:07 am
content: This works as well (testCount = 2 at end of main() )-Code:// Declared these globally so MPLABX debugger can see ituint8_t testCount;uint8_t *testCount_p = &testCount;uint8 myvar;void incrCount( uint8_t *counter ){*counter += 1; // This line increments by 1}int main ( void ){testCount = 0x00; // Initialize the count to = 0incrCount( &testCount );incrCount( &testCount );} // testCount = 2 as it should after 2 calls to incrCount( ).Regards, Dana.

author: leeatljs
author_rank: Contributor
timestamp: March 30, 2017, 10:34:42 am
content: Is this all the code?If you have any optimizations on, the compiler won't generate any code to modify these variables since they aren't used and have no side effects.Declare the variables as 'volatile' or get the pic to spit the result out on a serial port or something.Are you using the C30 or XC16 compiler?

author: grumpydoc
author_rank: Super Contributor
timestamp: March 30, 2017, 10:49:08 am
content: All seems a bit odd.Is this the real chip or the debugger/emulator onlyPost the assembly language output, as others have suggested.

author: Howardlong
author_rank: Super Contributor
timestamp: March 30, 2017, 10:49:22 am
content: The original code (plus #include stdint.h & xc.h) works OK on v1.30 XC16 both with no optimization and at opt level 3 in the simulator on MPLAB 8.92 using PIC24FJ256GB210.

author: Kilrah
author_rank: Unknown
timestamp: March 30, 2017, 10:55:37 am
content: Quote from: pyroesp on March 30, 2017, 09:10:34 amThis. With many microcontroller toolchains letting main() return creates undefined behavior. There is also no instruction after "incrCount( testCount_p );" to set a breakpoint on and see the value right after it has executed, so it isn't even clear how OP is reading the value. It most likely comes from reading it in a dodgy state much later than after the function has been called, and the processor having continued executing random stuff due to exiting main().Add a while(1); at the end of main() and set a breakpoint on that.

author: grumpydoc
author_rank: Super Contributor
timestamp: March 30, 2017, 10:58:55 am
content: Quote from: Howardlong on March 30, 2017, 10:49:22 am"plus #include stdint.h & xc.h" - I assumed that the OP had included the normal headers and just excluded them from the code snippet that he posted; but maybe not.I'd make sure that they are there - I can't check at the moment but I wonder if there is anything in the standard headers which affects where variables are allocated. Perhaps "testCount" has inadvertently been placed at an address which is used by the hardware.