Warnung bei Adresse auf Fkt.rückgabewert



  • Hallo,

    bekomme im Visual Studio 2008 eine Warnung bei diesem Codestück:

    a.Setze( &(b->GibC( )) );
    

    warning C4238: Nicht dem Standard entsprechende Erweiterung: R-Wert einer Klasse als L-Wert verwendet

    Kann ich diese Warnung ignorieren? Bei SetzeDelta übergebe ich die Adresse, in a.Setze() wird sofort eine Kopie (mit new) des Rückgabewerts gemacht. Es wird also nach der Zeile nie wieder auf den Rückgabewert zugegriffen.

    Sollte also unkritisch sein in dem Fall?



  • dasdasdasda schrieb:

    bekomme im Visual Studio 2008 eine Warnung bei diesem Codestück:

    a.Setze( &(b->GibC( )) );
    

    warning C4238: Nicht dem Standard entsprechende Erweiterung: R-Wert einer Klasse als L-Wert verwendet

    Kann ich diese Warnung ignorieren? Bei SetzeDelta übergebe ich die Adresse, in a.Setze() wird sofort eine Kopie (mit new) des Rückgabewerts gemacht. Es wird also nach der Zeile nie wieder auf den Rückgabewert zugegriffen.

    Sollte also unkritisch sein in dem Fall?

    Mach den Parameter doch einfach const-qualifiziert.



  • dasdasdasda schrieb:

    bekomme im Visual Studio 2008 eine Warnung bei diesem Codestück:

    a.Setze( &(b->GibC( )) );
    

    warning C4238: Nicht dem Standard entsprechende Erweiterung: R-Wert einer Klasse als L-Wert verwendet

    Kann ich diese Warnung ignorieren?

    Du kannst auch von der Brücke springen, schätze ich. Solltest du diese Warnung ignorieren? Nein.

    dasdasdasda schrieb:

    [...] in a.Setze() wird sofort eine Kopie (mit new) des Rückgabewerts gemacht.
    Es wird also nach der Zeile nie wieder auf den Rückgabewert zugegriffen.

    Dann nimm den Parameter doch per Referenz-auf-Const, so wie es fast jeder andere auch tun würde. Das ist dann portabel und kommt entsprechend ohne Warnung aus.

    👎

    struct irgendwas {};
    
    void setze(irgendwas* ptr)
    {
      irgendwas kopie = *ptr;
    }
    
    irgendwas quelle()
    {
      irgendwas i;
      return i;
    }
    
    int main()
    {
      setze(&quelle());
    }
    

    ➡

    👍

    struct irgendwas {};
    
    void setze(irgendwas const& ref)
    {
      irgendwas kopie = ref;
    }
    
    irgendwas quelle()
    {
      irgendwas i;
      return i;
    }
    
    int main()
    {
      setze(quelle());
    }
    


  • Ich brauch also einen L-Wert um mir davon die Adresse geben zu lassen.
    Also rein mit dem Fkt.wert in eine temp. Var und davon dann die Adresse genommen. So funktionierts jetzt ohne Warnung.

    Bei der Zeiger Lösung muss ich bleiben, weil ich die Variable auch auf "ungültig" setzen möchte.
    Gibts dafür eine Lösung ohne Zeiger?

    class xy
    {
    ...
    var* x;//diese var muss nicht unbedingt gesetzt sein
    ...
    };


  • Mod

    Du kannst die Funktion mit einer Referenzvariante überladen. Aber: Kann's sein, dass dein b->GibC( ) vielleicht eher selber einen Zeiger zurück geben soll? Irgendwie ist es nämlich komisch, eine Funktion die Zeiger erwartet mit Zeigern auf Funktionsrückgabewerten füttern zu wollen. Da ist designtechnisch irgendwie etwas falsch, wie die Komponenten ineinander greifen sollen.



  • SeppJ schrieb:

    Du kannst die Funktion mit einer Referenzvariante überladen. Aber: Kann's sein, dass dein b->GibC( ) vielleicht eher selber einen Zeiger zurück geben soll? Irgendwie ist es nämlich komisch, eine Funktion die Zeiger erwartet mit Zeigern auf Funktionsrückgabewerten füttern zu wollen. Da ist designtechnisch irgendwie etwas falsch, wie die Komponenten ineinander greifen sollen.

    ok danke.
    hab jetzt die übergabe der var als const reference gemacht, intern muss ich halt trotzdem mit Zeigern weiterarbeiten.


  • Mod

    dfvbgdfgd schrieb:

    ok danke.
    hab jetzt die übergabe der var als const reference gemacht, intern muss ich halt trotzdem mit Zeigern weiterarbeiten.

    😕 Erläutere das mal. Deine Implementierungsdetails sollten nämlich keinerlei Einfluss auf die Schnittstelle haben. Wenn du nun sagst, dass du einfach so die Schnittstelle ändern kannst, dann war sie vorher falsch und du brauchtest gar keine Pointer. Versuchst du etwa Funktionsparameter als lokale Variablen wiederzuverwenden?



  • SeppJ schrieb:

    dfvbgdfgd schrieb:

    ok danke.
    hab jetzt die übergabe der var als const reference gemacht, intern muss ich halt trotzdem mit Zeigern weiterarbeiten.

    😕 Erläutere das mal. Deine Implementierungsdetails sollten nämlich keinerlei Einfluss auf die Schnittstelle haben. Wenn du nun sagst, dass du einfach so die Schnittstelle ändern kannst, dann war sie vorher falsch und du brauchtest gar keine Pointer. Versuchst du etwa Funktionsparameter als lokale Variablen wiederzuverwenden?

    Hallo, danke für dein Interesse.
    Konkret gehts um folgendes:
    ich hab da eine wrapper klasse, die verschiedene realisierungen kapselt:

    class wrapper1
    {
    realisierung1_t* r1;
    realisierung2_t* r2;
    realisierung3_t* r3;
    };

    Nun kann es sein dass mal die eine, mal die andere, mal 2 Realisierungen gleichzeitig vorhanden sind.

    Jede Realisierung wiederum kann verschiedene andere Realisierungen zurück geben, welche dann wiederum von Wrapper2 gekapselt werden müssen. Also sowas in der Art wrapper2_objekt.setze(r1->GibRealiserung4()), welches mir Realisierung4_t zurückgibt.
    Genau an der Stelle muss ich aber intern in wrapper2 wieder einen Zeiger Realisierung4* speichern.

    class wrapper2
    {
    Realisierung4_t* r4;
    Realisierung5_t* r5;
    Realisierung6_t* r6;
    };

    Komplett das Design umwerfen geht nicht, ich muss einfach eine Schicht um die bestehenden Realiserungen legen, um eine gewisse neue Logik einzubauen.



  • Wenn GibRealiserung4() ein Objekt "by value" zurückgibt, dann wird dieses Objekt - vereinfacht gesagt - mit dem nächsten Strichpunkt zerstört.

    Einen Zeiger darauf zu speichern ist also ein Fehler, das Objekt existiert ja schon lange nicht mehr wenn der Zeiger dann verwendet wird.



  • hustbaer schrieb:

    Wenn GibRealiserung4() ein Objekt "by value" zurückgibt, dann wird dieses Objekt - vereinfacht gesagt - mit dem nächsten Strichpunkt zerstört.

    Einen Zeiger darauf zu speichern ist also ein Fehler, das Objekt existiert ja schon lange nicht mehr wenn der Zeiger dann verwendet wird.

    ich leg mir ja sofort eine kopie des objekts am heap an - noch bevor der strichpkt erreicht wurde - sofern der zeigerwert!=0.



  • Aha.
    Zeig mal Code.


Anmelden zum Antworten