Go Down

Topic: Funktion mit Wertrückgabe ? (Read 9605 times) previous topic - next topic

marcusw


Doc_Arduino

Hallo,

liest sich nicht schlecht. Ich bleibe erstmal bei meinen globalen Variablen. Sonst verstehe ich mein eigenes Programm später nicht mehr.  :D Nachdem ich Tage lang an dem Schweif gefummelt habe. Ich werde später darauf zurückkommen.



Tschau
Doc Arduino '\0'

Messschieber auslesen: http://forum.arduino.cc/index.php?topic=273445
EA-DOGM Display - Demos: http://forum.arduino.cc/index.php?topic=378279

red81

@jurs auch wenn der Thread schon alt ist hat dein Post hier ewiges suchen beendet.
Wenn ich referenziere, spart mir dass dann auch variablen Speicher? (wenn ich sie öfter mit unterschiedlichen Variablen aufrufe)
Und ist das korrekt das korrekt das Arrys standartmäßig referenziert werden?

Serenifly

#18
Nov 20, 2016, 12:28 am Last Edit: Nov 20, 2016, 12:29 am by Serenifly
Quote
Und ist das korrekt das korrekt das Arrys standartmäßig referenziert werden?
Arrays sind in C/C++ keine Objekte. Eine Array Variable zerfällt in einen Zeiger auf das erste Element. Bei Arrays wird also immer nur der Zeiger übergeben. Das ist auch der Grund weshalb man keine Arrays als Rückgabewert verwenden kann, bzw. keinen lokalen Arrays zurückgeben kann.

RudiDL5

Hmmm, da ich eher aus der Delphi-Ecke komme bin ich kein C++ Experte - aber solch trickreiche Typen-Rückgaben wie in #12 von Udo Klein erinnern mich stark an die "type x = record ... end;" aus Pascal. Daher habe ich heute morgen ein wenig experimentiert und festgestellt, dass die Arduino-IDE in dieser Hinsicht wohl um einiges verbessert worden ist. Solch Typen-Rückgaben wie beschrieben funktionieren zumindes ab der Version 1.6.7 auch ohne "namespace". Sogar so gut, dass man in der "struct" auch Arrays unterbringen kann:

Code: [Select]

// Typendeklaration
struct TArray
{
  byte arr[3];
};

// Beliebige Funktion mit Rückgabetyp "TArray"
TArray MyFunc( byte x )
{
  // Locale Var. vom Typ "TArray"
  TArray locVar;

  // Zuweisungen gemäß Input "x"
  locVar.arr[0] = 10 +x;
  locVar.arr[1] = 10 -x;
  locVar.arr[2] = 10 *x;

  // Rückgabe des Arrays (der Struktur)
  return locVar;
}

// Variable vom Typ "TArray"
TArray TestVar;
 
void setup() {
  Serial.begin(9600);
  
  TestVar = MyFunc(5);
  Serial.println( TestVar.arr[0] );  
  Serial.println( TestVar.arr[1] );  
  Serial.println( TestVar.arr[2] );  
}

void loop() {
}


Damit ist man sicherlich nicht mehr abwärtskompatibel. Und ob es ökonomisch in Bezug auf Speicherverwaltung ist kann ich nicht sagen. Wohl eher nicht. Dennoch funktioniert obiger Beispiel-Code bei mir ohne irgendwelche Probleme oder Warnungen und bietet Anreiz, damit weiter zu experimentieren.

Serenifly

#20
Nov 20, 2016, 07:13 pm Last Edit: Nov 20, 2016, 07:22 pm by Serenifly
Ja, der Prototyp Parser wurde was structs betrifft inzwischen etwas verbessert. Er macht aber manchmal immer noch Probleme.

Es geht auch ohne namespaces wenn man den Funktionsprototsyp einfach per Hand erstellt.


Ansonsten ist die Rückgabe von Objekten dank Return Value Optimization nicht so verschwenderisch wie es es auf den ersten Blick erscheint. Der Aufruf des Copy Konstructors kann wegoptimiert werden. Es wird Speicher in der aufrufenden Funktion angelegt und dieser wird direkt von der aufgerufenen Funktion beschrieben. Sieht man schön wenn man den Copy Konstruktor per Hand erstellt und darin eine serielle Ausgabe macht. Und dann diese Optimierung mal per -fno-elide-constructors deaktivert.

Code: [Select]
struct S
{
  S()
  {}
 
  S(const S&)
  {
    Serial.println("Kopie");
  }
};

S func()
{
  return S();
}

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

  S s = func();
}

void loop()
{
}

Das sollte normal nichts ausgeben

Mit -fno-elide-constructors kommt dagegen das:
Code: [Select]

Kopie
Kopie


Zwei Kopien weil das Objekt schon zwischen Erstellung und der Rückgabe in der Funktion einmal kopiert wird.

Go Up