chipKIT® Development Platform

Inspired by Arduino™

PmodJstkDspiInt C++ procedural question

Created Sun, 07 Feb 2016 23:09:55 +0000 by FredCailloux


Sun, 07 Feb 2016 23:09:55 +0000

Part of my DSPI learning is to thoroughly analyse the PmodJstkDspiInt DSPI sketch that is suggested as an example. In the Sketch function void AppTask() one can find these code lines:

AppTask()   {
  unsigned int	dwBtn; 
  dwBtn = fbBtnPmod & 0x01;   /* Check the state of button 1 and set LED 1 accordingly */
  if (dwBtn == 0) { digitalWrite(PIN_LED1, LOW); }
  else { digitalWrite(PIN_LED1, HIGH); }
  ...   ...  some more code and then function definition terminate with }

Question: why is the variable unsigned int dwBtn is flushed and reinstantiated every time the AppTask() is recalled ? Is that not a lost of controller resources ? Would it not have been better to declare this variable has a Global, like many others in the code ? Is it true to assume that this dwBtn variable will be destroyed and recreated at every recall, has AppTask() is part of the Sketch loop() function ? And that is a lost of uController resources ? :? Thanks for your say on this


Mon, 08 Feb 2016 10:33:32 +0000

As a general rule of thumb, in C++, you allocate variables in the narrowest scope possible. This means that you only ever use globals if the variable has to be accessed in more than one function. Any variable that is only used within a function should be defined within the function.

When a variable is defined in a function ("local" variable) it is allocated on the stack. That operation basically entails subtracting a number from the stack pointer, which is already being done to allocate space to store the call frame (to save the registers the function will change), so there is no extra overhead in performing that allocation. Instead of, for example, subtracting 100 it would subtract 104 (an integer is 4 bytes).

When the function returns that stack pointer is returned back to where it was. All very very fast and efficient.

Also, since the variable only exists while in the function, there is no static memory allocation for it, so two functions that run one after the other can use the same physical bits of memory to store their variables. If you had all your variables global you would end up wasting space since they will still exist when they are no longer needed, and other functions won't be able to re-use the space.

And then there's optimization. That small snippet, after compilation and optimization, may not even allocate the variable at all. It's not really needed to perform the logical "if", all you need is the result of the AND, and that can be stored in a register without having to be stored in RAM as well, since it is such a short-lived variable. So it may not even exist at all once compiled. Compare that to a global variable which most likely will exist regardless of the optimization.

So in summary: no, it is not right to have that variable as a global, and it is far more efficient on resources to keep it local.