Style question

In the snippet below the variable customchr_qty used to be the condition in the for loop. Reasoning that the variable is just a stand-in for the result of the calculation I substituted the calculation directly in the for and it works as expected. Now, is this considered good practice or not? I figure it saves a byte of RAM so that's good.

//byte customchr_qty = sizeof (theChrdata) / sizeof (customChrdef);

void setup() {
  Serial.begin(9600); // for debug only
  lcd.begin(16, 2);// open comms. with 1602 display unit
  /*
      Initialize custom graphic characters for LCD from PROGMEM
  */
  uint8_t * ccpoint;
  ccpoint = lcdbuffer;

  for (byte i = 0; i < sizeof (theChrdata) / sizeof (customChrdef); i++) {
    memcpy_P (&lcdbuffer, &theChrdata[i], sizeof (customChrdef));// this works, as proven by k loop below
    lcd.createChar(i, ccpoint);
  }

What I don't like about that sort of scheme is that it makes it impossible to print the calculated value for debugging purposes.

...R

I can see both sides. Since a . that last byte isn't critical here and 2 . the code is in setup(), I think I'll just go with the variable.

Thanks.

dougp:
I can see both sides. Since a . that last byte isn't critical here and 2 . the code is in setup(), I think I'll just go with the variable.

Thanks.

Or use a #define, which uses no memory.

Note that the compiler doesn't need to put 'const' values in RAM. It knows the value at compile time so it can just inserts the value into the code as immediate data. The should be smaller and faster than fetching the variable into a register and using the register.

This is the style I would have used.

const byte BytesPerCustomCharacter = 8;
const byte CustomChraracterData[][BytesPerCustomCharacter] PROGMEM = {
// Data Here!
};

const byte CustomChraracterCount = sizeof CustomChraracterData / BytesPerCustomCharacter;

void setup() {
  byte buf[BytesPerCustomCharacter];

  Serial.begin(9600); // for debug only
  lcd.begin(16, 2);// open comms. with 1602 display unit

  //      Initialize custom graphic characters for LCD from PROGMEM
  for (byte i = 0; i < CustomChraracterCount; i++) {
    memcpy_P (buf, &CustomChraracterData[i], BytesPerCustomCharacter);
    lcd.createChar(i, buf);
  }

Using a ‘local’ temporary variable this way is no big deal.
The memory used by the value will go out of scope at the end of the function, and be available/re-used elsewhere.

So many possibilities! It's like taking an eight ounce glass to Niagara Falls for a drink. After testing several suggestions and getting the same number for RAM usage it appears it all comes down to personal preference.

Thanks for the insights!

it’s also worth mentioning this is the reason even though the compiler/linker shows - say 80% memory utilisation, that number doesn’t account for transient use of memory by passed values, heap and stack usage.

it’s very common that even 10% free ‘memory’ is not enough. It all depends on how you toss the memory around within your code. e.g. globals and statics are convenient, but use permanent memory allocation.

If your sketch crashes or behaves oddly... apart from coding bugs, go looking for RAM optimisation to get that utilisation down as much as practical.

I went this way:

  for (byte i = 0; i < customchr_qty; i++) {
    memcpy_P (lcdPrintBufr, &ramGrfx[i], customChr_s);
    lcd.createChar(i, lcdPrintBufr);
  }

It's more compact and cleaner, to my eye, and no matter how I set it up memory usage was unchanged.

On the learning curve front, testing @johnwasser 's approach, it finally sunk in about the name of a character array being a pointer.

A nice side benefit is that on top of saving forty-eight bytes of RAM, flash usage dropped sixty-four bytes.

Thanks for your input!