I want to understand ....

Here I have two routines I “borrowed” from someone else’s code, I don’t remember where from…

They are used for reading and writing data from/to EEPROM (Nano).

//********************************************************
// Save settings to EEPROM
void settingsSAVE() {
  byte EEPROMAddress = SETTINGS_ADDRESS;
  const byte* pointer = (const byte*)(const void*)&settings;
  for (unsigned int i = 0; i < sizeof(settings); i++) EEPROM.write(EEPROMAddress++, *pointer++);
  } // void settingsSAVE()

//********************************************************
// Load settings from EEPROM
void settingsLOAD() {
  byte EEPROMAddress = SETTINGS_ADDRESS;
  byte* pointer = (byte*)(void*)&settings;
  for (unsigned int i = 0; i < sizeof(settings); i++) *pointer++ = EEPROM.read(EEPROMAddress++);
  } // void settingsLOAD()

I have some questions which may help me understand it better…

  1. Why would the “save” routine use “const” assignments for ‘pointer’, and the other not ?

  2. There is nothing in the reference documentation that explains the & (reference) and * (dereference) operators used in the pointer assignments in these snippets. I want to understand these if I can.

  3. Why do we have (void*) in the pointer assignments. Reference text says… "The void keyword is used only in function declarations. It indicates that the function is expected to return no information to the function from which it was called. " ?

I hope someone can help me understand these small but important pieces of code.

TIA

EDIT : perhaps I should have explained that there are only 2 external references… ‘SETTINGS_ADDRESS’ is #defined as 64
‘settings’ is a typedef struct

void* is a generic, anonymous pointer type - it can point to anything.

& is the "address of" operator in this context, not reference.

If you want to write to something a pointer points to, you don't want it to be constant. That's just commonsense.

AWOL:
If you want to write to something a pointer points to, you don't want it to be constant. That's just commonsense.

Thanks AWOL....

So this indicates the use of 'const' declarations in settingsSAVE is erroneous ??? If so, why does it work ?

Also, could these 2 routines be merged into 1, with a parameter to select the operation to be performed, LOAD or SAVE ?

settingsSAVE isn't changing the thing it points at so it's absolutely fine. That's const correctness even :slight_smile:

And to note, this stuff is now included in the Arduino IDE as EEPROM.put() and EEPROM.get() :slight_smile:

daba:
So this indicates the use of 'const' declarations in settingsSAVE is erroneous ???

I'm not following your reasoning there. You're not writing to what the pointer points to.

Also, could these 2 routines be merged into 1, with a parameter to select the operation to be performed, LOAD or SAVE ?

You could, but I can't see why you'd want to.

Thanks for the comments people, I now have a much better understanding …

I’ll just continue to use it “as is”, knowing that it has “const correctness” :slight_smile:

Or witch to the build in functions :wink:

septillion:
Or witch to the build in functions :wink:

I agree, done, and much easier on the eye !

// respond to the Save button
  if (RemoteXY.save_button) {
    RemoteXY.save_button = 0;
    
// turn the LEDs off for visual indication
    analogWrite(pin_RED,0);
    analogWrite(pin_GRN,0);
    analogWrite(pin_BLU,0);
    
    settings.RED = RemoteXY.RED; 
    settings.GRN = RemoteXY.GRN; 
    settings.BLU = RemoteXY.BLU; 

    EEPROM.put(SETTINGS_ADDRESS, settings);

    delay(750);
  }

If the settings are globals, you could write a really simple wrapper for each of save and retrieve, rather than have to pass a function code.