Änderung eines Funktionsparameters führt zum Verschwinden der Konsolenausgabe !?



  • Ich versuche mich ein wenig an CPP da ich es für die ARDUINO-Programmierung benötige und lese mich da gerade ein wenig ein. Hier ein paar Gedanken zum Quellcode der weiter unten zu finden ist. Was die SWAP-Funktion tun soll ist klar. Genau das hat sie auch gemacht. Danach habe ich ein wenig herum gespielt. Da nach dem KONSTANT-SETZEN der Parameter die Funktion so nicht mehr funktionierte wollte ich einfach eine Ausgabe machen. Ich weiss die WERTE werden nicht wirklich vertauscht. Jetzt mein Problem: Sobald ich den &a-Parameter KONSTANT deklariere, so wie es im Code zu sehen ist, bekomme ich keine Ausgabe in der Konsole mehr, was meiner Meinung nach absolut keinen SINN ergibt. Wenn ich "const" wieder lösche funktioniert es problemlos. Kann mir dafür jemand ein Erkärung geben!?

    #include <iostream> //Einbinden von IOStream
    
    using namespace std;
    
    void swap(const int &a,int &b) {
    //	int tmp = a; // "temporärer" Variable den Wert von Variable a zuweisen
    //	a = b; // a mit dem Wert von Variable b überschreiben
    //	b = tmp; // b den Wert der "temporären" Variable zuweisen (Anfangswert von Variable a)
    	cout << "Die vertauschten Werte sind: a=" << b << " und b=" << a << endl;
    }
    int main() {
    	int x = 5, y = 10;
    	swap(x, y);
    	return 0;
    }
    
    
    

    Ich könnte das einfach ignorieren da es für mich eigentlich nicht so wichtig ist. Allerdings wenn mir das mal unbewusst passiert wird es schwer den Fehler in einem grösseren Projekt zu finden. Also frage ich hier einfach mal nach ob jemand da weiß was los ist.



  • Möglicherweise inkludiert iostream weitere Header ein, die irgendwann selbst std::swap sichtbar machen. Dann wird nicht dein swap aufgerufen, sondern std::swap. Kommentier´ mal das using namespace std aus und probier´s noch mal.



  • Tipp: Entferne mal using namespace std; (und schreibe dann std::cout)!

    Es gibt schon eine Funktion swap im std-Namensbereich und diese wird dann bei swap(x, y)aufgerufen, da die Parameter darauf direkt passen (ohne Konvertierung).

    Das const ergibt bei der swap-Funktion ja auch keinen Sinn, da die Variablen ja geändert werden sollen.

    Wenn du doch diese Funktion immer aufrufen wolltest, dann sollte auch der Parameter konstant sein:

    const int x = 5;
    int y = 10;
    swap(x, y);
    

    s.a. Ideone-Code

    PS: Eigentlich ist std::swap im Header <algorithm> (als Template) definiert, aber es wird wahrscheinlich indirekt über <iostream> eingebunden.



  • Ihr seid so SUPER. Es lag tatsächlich daran dass eine andere SWAP-Funktion aufgerufen wurde. Nachdem ich "cout" und "endl" direkt adressiert habe klappte es wunderbar :D. VIELEN DANK. Wieder was dazu gelernt. Hey und das die SWAP-Funktion so keinen Sinn macht war mir schon bewusst. Wurde nur vom Author das Buches angehalten ein wenig mit dem Quellcode herum zu experimentieren und das Ergebniss kennt ihr. Toll daß mir so schnell weiter geholfen wurde und es auch nicht wirklich kompliziert war den Fehler nach zu vollziehen. Eines noch: Das bedeutet dann wohl daß die Library-Funktionen immer Vorrang haben vor den Selbst-Porgrammierten !?

    lg der UuugUuug



  • Es gibt keine Priorisierung zwischen Funktionen aus der Standard-Library und eigenen Code, sondern nur, wie schon geschrieben, welche Parameter besser passen.

    Du kannst alternativ auch eigene Namensbereiche anlegen (namespace my { ... }) und diese dann explizit verwenden: my::swap(x,y).

    PS: Außerdem noch erwähnenswert, daß du explizit die Konvertierung mittels swap(static_cast<const int &>(x), y); durchführen kannst (bei int x).



  • Wär cool, wenn das jemand exakt erklären könnte. Ich weiß nur, dass bei der Überladungsauflösung bei exakter Übereinstimmung Nicht-Templates bevorzugt werden. Würde es etwas ändern, wenn man x in der main als const int deklarieren würde? Mir ist nicht ganz klar, ob und wenn ja wieso das eine Rolle spielt.



  • Ich wunder mich da auch immer wieder, besonders, wenn Templates im Spiel sind. Hier der cppreference Artikel zum
    Argument Dependent Lookup



  • Standard conversion sequence S1 is a better conversion sequence than standard conversion sequence S2 if:

    • [...]
    • S1 and S2 are reference bindings (8.5.3), and the types to which the references refer are the same type except for top-level cv-qualifiers, and the type to which the reference initialized by S2 refers is more cv-qualified than the type to which the reference initialized by S1 refers.

    Ja, wenn man dem ersten Paramater constness zucastet, wird die gedachte Überladung verwendet.



  • @Th69 Danke für die INFO, das mit den eigenen Namensbereichen hatte ich schon gelesen, nur noch nicht verinnerlicht und daß das bei meinem Beispiel auch Sinn machen würde. Natürlich hast du recht. Mir fehlt halt noch die Praxis da ich noch zu wenig Erfahrung habe C++ betreffend.


Anmelden zum Antworten