Call-By-Reference Unterschied zwischen Compiler von MS und MinGW

m0zkit0

Grünschnabel
Hallo,

ich hoffe die Frage ist hier richtig und auch noch nicht gestellt. Zumindest habe ich nichts brauchbares zu meinen Suchbegriffen gefunden.

Ich habe folgendes Stückchen Code versucht unter MSC und MinGW GCC zu kompilieren und dabei festgestellt, dass der GCC es nicht kann/will.

Code:
#include <string>
 
using namespace std;
 
void tueWas(string& str);

int main(void)
{
	tueWas(string("Hallo"));

	return 0;
}


void tueWas(string& str)
{
	printf(str.c_str());
}

Unter MinGW (g++ (GCC) 4.3.3-dw2-tdm-1) kommt folgende Fehlermeldung bei absolut demselben Sourcecode (die hervorgehobenen Stellen sind die Zeilen, welche in der Fehlermeldung angesprochen werden):
Code:
g++ -O0 -g3 -Wall -c -fmessage-length=0 -osrc\Test.o ..\src\Test.cpp
..\src\Test.cpp: In function 'int main()':
..\src\Test.cpp:9: error: invalid initialization of non-const reference of type 'std::string&' from a temporary of type 'std::string'
..\src\Test.cpp:5: error: in passing argument 1 of 'void tueWas(std::string&)'
Als Workaround habe ich bisher immer das Objekt vorher erzeugt und dann übergeben, was ohne Probleme funktioniert.
Code:
int main(void)
{
	string str("Hallo");
	tueWas(str);

	return 0;
}
Nun meine Frage: Weiss jmd warum das so ist, bzw. gibt es einen Grund warum dieses Kontrukt vom GCC abgelehnt wird oder andersherum warum es Microsoft erlaubt?

Vielen Dank im Vorraus.

Mit freundlichen Grüßen

m0zi
 
Hallo,

probier es mal mit der Signatur
C++:
void tueWas(const string& str);
. Die Fehlermeldung weist ja auf das fehlende const hin. Im Zweifelsfalle würde ich vermuten, dass das ein "Feature" des MSVC-Compilers ist, dass es dort funktioniert und GCC sich an den Standard hält. Genau weiß ich es aber nicht. Ich finde das Verhalten von GCC zumindest nachvollziehbar.

Grüße, Matthias
 
Hi.
Die Fehlermeldung weist ja auf das fehlende const hin. Im Zweifelsfalle würde ich vermuten, dass das ein "Feature" des MSVC-Compilers ist, dass es dort funktioniert und GCC sich an den Standard hält. Genau weiß ich es aber nicht.
Also ich würde das eher einen "Bug" des MS Compilers nennen. :)

Es ist aber tatsächlich so, das der C++ Standard vorschreibt, das man keine temporären Objekte als Argument an nicht-konstante Referenzen übergeben darf. Die Logik dahinter: über die Referenz kann die Funktion natürlich den Wert des übergebenen Objekts ändern; aber was hätte das bei einem temp. Objekt für einen Sinn? Man kommt nicht mehr an das temp. Objekt heran, und der Compiler muss dafür sorgen das temp. Objekte am Ende der Anweisung wieder wegzuräumen.

Außerdem gehört es zur sog. "Const-Correctness" Parameter die einer Funktion / Methode übergeben werden, welche innerhalb der Funktion nicht verändert werden als const zu deklarieren.

Gruß
 
Vielen Dank an die Antwortenden.

Die Erklärung ist durchaus verständlich, auch wenn ich die Const-Benutzung als etwas überbewertet einschätze. Leider habe ich erst Java gelernt, wo das äquivalente Schlüsselwort "final" meiner Ansicht nach nicht die gleiche Bedeutung hat, wie in C++.

Es ist ja okay, wenn der GCC meckert, wenn man einen nicht konstanten Parameter mit einem temporären Wert belierfert, aber gleich einen Fehler draus machen

Oder habe ich da etwas falsch verstanden? Wenn eine Methode sagt, einer ihrer Parameter sei "const", dann gibt sie doch quasi nur an, dass diese Methode den Parameter nicht verändern wird. Allerdings kann ich dann nicht verstehen, warum ich dieser Methode nicht auch einen temporären nicht "const" Wert übergeben kann, wie es ja der Fall war? Nun gut, sicherlich kann man dabei über die Sinnhaftigkeit streiten :offtopic:.

Da du ja von dem C++-Standard gesprochen hast: Ist schon richtig, dass GCC sich da (zumindest soweit es geht) an C++98/03 hält? Und weiss jmd vielleicht wo man das sich anschauen kann (kostenlos:))?
 
Die Erklärung ist durchaus verständlich, auch wenn ich die Const-Benutzung als etwas überbewertet einschätze. Leider habe ich erst Java gelernt, wo das äquivalente Schlüsselwort "final" meiner Ansicht nach nicht die gleiche Bedeutung hat, wie in C++.
Es gibt einige Unterschiede zw. Java und C++. Auf die const-correctness wurde in Java nicht viel Wert gelegt, allerdings sind Strings in Java auch immutable - in C++ nicht.
Es ist ja okay, wenn der GCC meckert, wenn man einen nicht konstanten Parameter mit einem temporären Wert belierfert, aber gleich einen Fehler draus machen
Es ist nunmal Vorschrift und soll den Programmierer vor Fehlern schützen.
Oder habe ich da etwas falsch verstanden? Wenn eine Methode sagt, einer ihrer Parameter sei "const", dann gibt sie doch quasi nur an, dass diese Methode den Parameter nicht verändern wird.
Ja.
Allerdings kann ich dann nicht verstehen, warum ich dieser Methode nicht auch einen temporären nicht "const" Wert übergeben kann, wie es ja der Fall war?
Das das temp. Objekt nicht const ist nicht der Punkt. Wäre es const, hättest du es erst recht nicht übergeben können, da der const Modifizierer hätte verworfen werden müssen. Warum der GCc deinen Code nicht akzeptierte hab ich ja schon begründet: es ist nicht erlaubt und macht in der Regel keinen Sinn.
Da du ja von dem C++-Standard gesprochen hast: Ist schon richtig, dass GCC sich da (zumindest soweit es geht) an C++98/03 hält? Und weiss jmd vielleicht wo man das sich anschauen kann (kostenlos:))?
Hier ist zumindest ein Entwurf den ich auf die Schnelle gefunden hab: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2914.pdf oder http://www.kuzbass.ru:8086/docs/isocpp/

Gruß
 
Zuletzt bearbeitet:
Habe leider zu den Reference nicht direkt was gefunden. Lediglich 12.2 - Temporary objects, welches auch funktioniert, wobei hier ja kein Call-By-Reference gemacht wird.

Vielen Dank nochmals.

Bis denne
 
Zurück