Subtraktion mit "value by reference" nicht möglich

Hallo,

ist es normal das man eine Subtraktion oder vielleicht sonstige Formel nicht mit "call by reference" an eine Funktion übergeben kann?
Ich dachte der Compiler weiß das er das Ergebnis an die Funktion übergeben muss. Bin ratlos.

Ich kann mir derzeit nur behelfen indem ich eine Hilfsvariable verwende und diese der Funktion übergebe. Oder ich übergebe den Wert "call by value".

Mach ich etwas falsch oder gehts einfach nicht mit Formel?

Testsketch was ich meine

struct t_data
{
  volatile bool flag_detect = false;
  int32_t value_rel = 0;
  int32_t value_abs = 0;
  int32_t value_ref = 0;
  float result_m = 0.0;
  float result_i = 0.0;
  const float div_m = 806.34;     // Umrechnung in [mm]   >> 1 mm entspricht 806,339 Schritte
  const float div_i = 20481.0;    // Umrechnung in [inch] >> 1 inch entspricht 20481 Schritte
} mess;

void setup() {
  Serial.begin(250000);

  int32_t diff = mess.value_abs - mess.value_ref;
  convert(diff);                                  // kompiliert


  convert(mess.value_abs - mess.value_ref);       // kompiliert nicht
}

void loop() {
 
}


void convert (int32_t &data)                    // oder ändern in call by value by copy
{  
  switch (data) {
    // Gültigkeitsbereiche //
    case        0 ...   125000:  mess.result_m = (data/mess.div_m * -1);            // Umrechnung in [mm] für negative Werte
                                 mess.result_i = (data/mess.div_i * -1);            // Umrechnung in [inch] für negative Werte  
                                 show_measurement (mess.result_m, mess.result_i);
                                 break;
    case  4150000 ...  4300000:  mess.result_m = (data/mess.div_m);                 // Umrechnung in [mm] Absolutwert
                                 mess.result_i = (data/mess.div_i);                 // Umrechnung in [inch] Absolutwert 
                                 show_measurement (mess.result_m, mess.result_i);
                                 break;                             
    case 16650000 ... 16777215:  mess.result_m = (16777215-data)/mess.div_m;        // Umrechnung in [mm] für positive Werte
                                 mess.result_i = (16777215-data)/mess.div_i;        // Umrechnung in [inch] für positive Werte 
                                 show_measurement (mess.result_m, mess.result_i);
                                 break;
    default:                     break;
  }
}


void show_measurement (float &metric, float &inch)
{
  Serial.print(metric,2);        // Anzeige in [mm]
  Serial.print(F(" mm ")); 
  Serial.print('\t');
  Serial.print(inch,3);          // Anzeige in [inch]
  Serial.print(F(" inch")); 
}

Arduino: 1.8.5 (Windows 10), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"

sketch_jun25a.ino: In function 'void setup()':

sketch_jun25a:19: error: invalid initialization of non-const reference of type 'int32_t& {aka long int&}' from an rvalue of type 'int32_t {aka long int}'

convert(mess.value_abs - mess.value_ref); // kompiliert nicht

^

sketch_jun25a.ino:27:6: note: in passing argument 1 of 'void convert(int32_t&)'

void convert (int32_t &data) // oder ändern in call by value

^

exit status 1
invalid initialization of non-const reference of type 'int32_t& {aka long int&}' from an rvalue of type 'int32_t {aka long int}'

Bitte schlage den Unterschied zwischen lvalue und rvalue nach! Von einem temporären Wert kannst du natürlich nicht eine Referenz nehmen. Was soll das sein?

Und wieso übergibst du hier überhaupt eine Referenz? Völlig unnötig

Mach dir klar, was 'Call by reference' bedeutet. Letztendlich übergibst Du einen Pointer auf eine Variable. Früher in reinem 'C' musste man sowas mit Pointerschreibweise 'von Hand' machen. Jetzt macht das der Compiler für dich. Unter der Haube bleibt es aber letzendlich das Gleiche. Wenn Du jetzt da einen arithmetischen Ausdruck hinschreibst - wo soll da der Pointer hinzeigen?

Hallo,

gut, Denkfehler. Meine Überlegung war das der temporäre Wert ja auch in irgendeiner Adresse steht die der Funktion übergeben werden kann/könnte. Gut - geht so nicht.

call by reference ... Warum nicht? Auch hier war meine Überlegung gewesen das nicht sinnlos 4 Byte am laufenden Band rum und num kopiert werden müssen. In dem Fall macht das die Hilfsvariable wieder zu nicht. Demzufolge nehme ich nun call by value.

Danke.

Eine Referenz belegt auch zwei Bytes. Viel sparst du damit nicht. Wenn du dein ganzes struct an eine Funktion übergeben wolltest wäre das was anderes. Oder ein String Objekt.