Copying Structure data into identical Structure Compile Error

sketch_oct25a:48: error: assignment of read-only location ‘(_Destination + ((sizetype)i))’
_Destination = _Source;
_
^_
exit status 1
assignment of read-only location '(_Destination + ((sizetype)i))’[/quote]

Goal is to copy ANY Structure data into a clone of itself. Proof of concept code. This is testing for a bigger project to transfer structures between a UNO and an ESP8266.
What am I doing wrong?
```
*typedef struct GPSLocation{
  double Log ;
  double Lat;
  char RawData[128];
};

GPSLocation GPSData; // Source Data Structure
GPSLocation RGPSData; // Destination Data Structure

void PrintGPSLocation(GPSLocation * GPS) {
  Serial.print("GPS Location\nLon: ");
  Serial.println(GPS->Log, 3);
  Serial.print("Lat: ");
  Serial.println(GPS->Lat, 3);
  Serial.print("RawData: ");
  Serial.println(GPS->RawData);
}

void setup() {
  Serial.begin(115200);
  Serial.println(“Structure Data Transfer Test”);
  delay(100);
// Load the Source
  GPSData.Log = 01131.000;
  GPSData.Lat = 4807.038;
  memcpy(GPSData.RawData, “$GPGGA, 123519, 4807.038, N, 01131.000, E, 1, 08, 0.9, 545.4, M, 46.9, M, , * 47”, sizeof("$GPGGA, 123519, 4807.038, N, 01131.000, E, 1, 08, 0.9, 545.4, M, 46.9, M, , * 47"));
}

void loop() {
  Serial.println( sizeof(GPSLocation));
  Serial.println( sizeof(GPSData));

PrintGPSLocation(&GPSData);

CopyStructure( GPSData, RGPSData);

PrintGPSLocation(&RGPSData);

while (1) {}
}

template uint16_t CopyStructure( const T& Source, const T& Destination) {
  int i;
  const byte* _Source = (const byte*)(const void*)&Source;
  const byte* _Destination = (const byte*)(const void*)&Destination;
  for (i = 0; i < sizeof(Source); i++) {
    _Destination[i] = _Source[i];
  }
}*

```
Thanks in advance
Z

const byte* _Destination = (const byte*)(const void*)&Destination;

You are explicitly telling the compiler that the destination address is read-only, then asking it to write there....

Regards, Ray L.

BTW - In c++, "typedef struct" is not necessary. A struct is exactly like a class, except all member data is public by default. So, the struct becomes a type automatically.

You can just use:

struct GPSLocation{
  double Log ;
  double Lat;
  char RawData[128];
};

Regards, Ray L.

RayLivingston:

const byte* _Destination = (const byte*)(const void*)&Destination;

You are explicitly telling the compiler that the destination address is read-only, then asking it to write there…

Regards,
Ray L.

Yep I see that const in there thanks for the simple pointer… brain fart.

struct GPSLocation{
  double Log ;
  double Lat;
  char RawData[128];
};

GPSLocation GPSData; // Source Data Structure
GPSLocation RGPSData; // Destination Data Structure

void PrintGPSLocation(GPSLocation * GPS) {
  Serial.print("GPS Location\nLon: ");
  Serial.println(GPS->Log, 3);
  Serial.print("Lat: ");
  Serial.println(GPS->Lat, 3);
  Serial.print("RawData: ");
  Serial.println(GPS->RawData);
}

void setup() {
  Serial.begin(115200);
  Serial.println("Structure Data Transfer Test");
  delay(100);
// Load the Source
  GPSData.Log = 01131.000;
  GPSData.Lat = 4807.038;
  memcpy(GPSData.RawData, "$GPGGA, 123519, 4807.038, N, 01131.000, E, 1, 08, 0.9, 545.4, M, 46.9, M, , * 47", sizeof("$GPGGA, 123519, 4807.038, N, 01131.000, E, 1, 08, 0.9, 545.4, M, 46.9, M, , * 47"));
}

void loop() {
  Serial.println( sizeof(GPSLocation));
  Serial.println( sizeof(GPSData));

  PrintGPSLocation(&GPSData);

  CopyStructure( GPSData, RGPSData);

  PrintGPSLocation(&RGPSData);

  while (1) {}
}


template <class T> uint16_t CopyStructure( const T& Source, const T& Destination) {
  int i;
  const byte* _Source = (const byte*)(const void*)&Source;
  byte* _Destination = (const byte*)(const void*)&Destination;
  for (i = 0; i < sizeof(Source); i++) {
    _Destination[i] = _Source[i];
  }
}

While we're at it, if you're copying a string, why not simply use strcpy instead of memcpy? Better still, use strncpy, and for the length, use the length of the array in the struct, rather than the length of the source string

Regards, Ray L.

Thank you RayLivingston,

Your suggestions are helpful and would simplify and speed up this function if this was the end result, Thanks.

This is part of a bigger picture

What I needed to do is convert any data type char, int, byte, long, arrays of each and Structures into byte array. At the moment I plan on only using Structures to transfer data but any of the above should work. What I mean by transfer data is that I have an Excellent way of sending 32 bytes of data through ISP between an UNO and an ESP8266. This test was my missing link and it solved many of the issues I was facing before.

Sequence will be Uno converts any structure to chunks of 32bytes then sends it over ISP to an ESP8266 where the esp reconstructs it back into the same formatted Structure. This can be done the other way around also.

Advantages Frees up Serial Ports for testing and programming also it takes up a small footprint because of the hardware support on both sides. The rate of transfer is fast I was running test with 1000's of 32 byte chunks (265000 baud+) transferring per second with no errors.

I will post updates to the final usage of this function here for all, Stay tuned :)

Thanks again everyone

Z

Type orders are a bit counter-intuitive in C++. They're interpreted back-to-front.

const int * (and the identical int const *) is interpreted as a pointer to a constant integer. If you want a constant pointer to an integer, you need to declare it int * const.

const int * is a mutable pointer that dereferences to a constant integer.

int * const is a constant pointer that dereferences to a mutable integer.

Useful in decoding declarations -

http://cdecl.org