-1

In bellow example why we should use int32_t instead of uint32_t ? (platform is ARM 32 bit microcontroller)

struct tcb{
  int32_t *stackPt;       
  struct tcb *nextPt;  
};

It's a part of RTOS tutorial. and tcb is for thread control block . why we should use int32_t* for stack ?

Morteza N
  • 3
  • 3
  • 1
    You're right, its impossible for the stackpointer to get negative, on the other hand 2147483647 should be enough for your embedded platform. So if there's no reason you have to explicit use uint32_t, make the compiler happy and use int32_t – Kraego Apr 21 '21 at 14:09
  • @kraego you missed the *. The question is whether it is a pointer TO signed int or unsigned it, not whether the pointer itself is signed. – Tom V Apr 21 '21 at 14:11
  • @TomV okay if so, maybe this is interesting: https://stackoverflow.com/questions/27625301/difference-between-unsigned-and-signed-int-pointer – Kraego Apr 21 '21 at 14:18
  • For some reason folks like to declare variables as signed, and only change to unsigned for specific cases. I am the other way I make everything unsigned and only do signed in the very rare cases it is needed. This is probably a side effect of that. Unsigned is easier to pick apart the stack item. OR without other context this may simply be a way to store the pointer for context switching and in that case any variable type will work, address bits are address bits.... bits is bits. – old_timer Apr 21 '21 at 15:06

1 Answers1

0

There is no particular reason that you should use pointer to signed rather than unsigned.

You are probably never going to dereference this pointer directly to access the words on the stack. If you do want to access the data on the stack, some of it will be signed, some unsigned, and some neither (strings etc) so the pointer type will not help you with that.

When you want to pass around a pointer but never dereference it then one convention is to use a pointer to void, but that convention isn't so popular in embedded system code.

One reason to use a pointer to a 32-bit integer is to suggest that the pointer is at least word-aligned. If you intend on complying with the ARM EABI (which you should) then the stack should be doubleword (64-bit) aligned at the entry to every EABI compliant function. To hint that that is the case you might want to even use a (u)int64_t pointer. This might be misleading though because not everything on the stack is 64-bit or 32-bit aligned, just the whole frames.

Tom V
  • 4,827
  • 2
  • 5
  • 22
  • So that was about pointer to stack what about stack itself ? for example : "int32_t TCB_STACK[NUM_OF_THREADS][STACKSIZE];" Is it because of that we use negative number in our program ? for example when scheduler wants to change thread ,there would be negative number in processor registers ? so for pushing to stack should it be signed ? – Morteza N Apr 21 '21 at 15:32
  • If you are declaring an array to use as a stack then you should definitely use a 64-bit type to get the maximum alignment, but it doesn't matter if it is signed or unsigned. The data on the stack will be both, so some will be incorrect whichever you choose. – Tom V Apr 21 '21 at 16:01
  • Imagine we have an big uint32_t data in processor register and it's time to change Thread so if stack array be type of int32_t which is singed ,will we miss data in this stacking and unstacking ? will processor understand which data was a big unsinged value and not a negative value ? and if the answer is yes how ? – Morteza N Apr 21 '21 at 16:17
  • An integer is neither signed nor unsigned when it is in a register. For example if you add two registers, then if the two input values were unsigned then the result is correct as an unsigned, but if they were signed then the same instruction produces the same result which is is correct as signed. Only certain instructions care about the difference, for example right-shift, you have to use a different instruction depending on the type, but then the type is encoded in the instruction not stored in the register. – Tom V Apr 21 '21 at 19:28