Als ich meinen C ++ - Code zum ersten Mal mit GCC 4.3 kompilierte (nachdem ich ihn erfolgreich ohne Warnungen in 4.1, 4.0, 3.4 mit den -Wall -Wextra
Optionen kompiliert hatte ), bekam ich plötzlich eine Reihe von Fehlern im Formular warning: type qualifiers ignored on function return type
.
Bedenken Sie temp.cpp
:
class Something
{
public:
const int getConstThing() const {
return _cMyInt;
}
const int getNonconstThing() const {
return _myInt;
}
const int& getConstReference() const {
return _myInt;
}
int& getNonconstReference() {
return _myInt;
}
void setInt(const int newValue) {
_myInt = newValue;
}
Something() : _cMyInt( 3 ) {
_myInt = 2;
}
private:
const int _cMyInt;
int _myInt;
};
Laufen g++ temp.cpp -Wextra -c -o blah.o
:
temp.cpp:4: warning: type qualifiers ignored on function return type
temp.cpp:7: warning: type qualifiers ignored on function return type
Kann mir jemand sagen, was ich falsch mache, was gegen den C ++ - Standard verstößt? Ich nehme an, dass bei der Rückkehr nach Wert die Führung const
überflüssig ist, aber ich habe Probleme zu verstehen, warum es notwendig ist, damit eine Warnung zu generieren. Gibt es andere Orte, an denen ich die Konstante weglassen sollte?
c++
constants
gcc-warning
Seth Johnson
quelle
quelle
warning: type qualifiers ignored on function return type
etwaswarning: please don't add const qualifier when you are returning by value
.const
Qualifikationsmerkmal nicht zur Funktion hinzufügen , die einen Wert zurückgibt ? Wir tun dies, weil wir nicht möchten, dass sich der Wert danach ändern kann.Antworten:
Es verstößt nicht gegen den Standard. Deshalb sind sie Warnungen und keine Fehler .
Und in der Tat haben Sie Recht - die Führung
const
ist überflüssig. Der Compiler warnt Sie, weil Sie Code hinzugefügt haben, der unter anderen Umständen etwas bedeuten könnte, aber unter diesen Umständen nichts bedeutet, und er möchte sicherstellen, dass Sie später nicht enttäuscht werden, wenn sich Ihre Rückgabewerte schließlich als änderbar herausstellen.quelle
sizeof(void)
warnen ebenfalls nur, sind aber eindeutig verboten. Der Standard kennt den Unterschied zwischen Warnungen und Fehlern nicht: Beide sind Diagnosen.Diese Warnung ist beim Kompilieren von Code mit Boost.ProgramOptions aufgetreten. Ich benutze es,
-Werror
damit die Warnung meinen Build beendet, aber da die Quelle der Warnung in den Tiefen von Boost lag, konnte ich sie nicht durch Ändern meines Codes beseitigen.Nach langem Suchen habe ich die Compiler-Option gefunden, die die Warnung deaktiviert:
Hoffe das hilft.
quelle
-isystem
anstelle von-I
, wodurch alle von Boost-Headern ausgelösten Warnungen unterdrückt werden.Die Rückgabe eines konstanten Werts ist nur sinnvoll, wenn Sie eine Referenz oder einen Zeiger (in diesem Fall einen Zeiger auf eine Konstante und keinen konstanten Zeiger) zurückgeben, da der Aufrufer den referenzierten Wert (auf den verwiesen wird) ändern kann.
Ein weiterer Kommentar zum Code, der nicht mit Ihrer Frage zusammenhängt: Ich denke, es ist besser, einen Setter anstelle von zu verwenden
int& getNonconstReference() { return _myInt; }
Welcher Wille sollte sein:
void setMyInt(int n) { _myInt = n; }
Darüber hinaus ist es sinnlos, eine const-Referenz auf ein int zurückzugeben. Dies ist sinnvoll für ein größeres Objekt, dessen Kopieren oder Verschieben teurer ist.
quelle
Das haben
struct Foo { Foo(int) {} operator bool() { return true; } };
und das
Foo some_calculation(int a, int b) { Foo result(a + b); /*...*/ return result; }
das Beispiel
if (some_calculation(3, 20) = 40) { /*...*/ }
Kompiliert ohne Vorwarnung. Das ist natürlich selten. Aber ist es nicht richtig, es den Menschen schwer zu machen, Dinge falsch zu machen? Und mit der Erwartung, dass Leute Dinge ausprobieren, die falsch sind, sollte der Rückgabetyp als const deklariert werden. Und: g ++ warnt vor dem Ignorieren des Klassifikators, ignoriert ihn jedoch nicht. Ich denke, die Warnung bezieht sich auf Benutzer, die die Kopie nehmen und die const-Klassifizierer auf ihrer Kopie ignorieren. Dies sollte jedoch keine Warnung sein, da dies ein absolut korrektes Verhalten ist. Und das macht Sinn.
quelle
const
. Dasconst
Qualifikationsmerkmal wird nur für Rückgabewerte vom Typ Nichtklasse ignoriert.Sollte -pedantic nicht nur die strikte Einhaltung des ISO-Standards erlauben? Abhängig von -std = natürlich ...
quelle
Diese Warnung ist auch nützlich, um Verwirrung zu vermeiden, wenn Funktionen deklariert werden, die Zeiger auf Objekte zurückgeben, die nicht geändert werden sollten:
// "warning: type qualifiers ignored on function return type" // as the pointer is copied. Foo* const bar(); // correct: const Foo* bar();
quelle
Es gibt einen Unterschied zwischen
const
einem Basistyp-Ergebnis, bei dem es ignoriert wird, undconst
einem Klassentyp-Ergebnis, bei dem es im Allgemeinen Chaos anrichtet.namespace i { auto f() -> int const { return 42; } void g( int&& ) {} } namespace s { struct S {}; auto f() -> S const { return {}; } auto g( S&& ) {} } auto main() -> int { { using namespace i; g( f() ); } // OK { using namespace s; g( f() ); } // !The `const` prevents this. }
Aus diesem Grund warnt der Compiler im ersten Fall: Es ist ein Sonderfall, der möglicherweise nicht das tut, was man naiv erwarten kann.
Für die moderne Programmierung wäre es meiner Meinung nach auch nett, eine Warnung über das
const
Klassentyp-Ergebnis zu erhalten, da es die Bewegungssemantik verbietet. ziemlich hohe Kosten für jeden kleinen Vorteil, den man sich vorgestellt hatte.quelle
Scott Meyers wies darauf hin, dass es einen guten Grund gibt, warum jemand
const
Werte zurückgebenmöchte. Hier ist ein Beispiel:int some_calculation(int a, int b) { int res = 0; /* ... */ return res; } /* Test if the result of the calculation equals 40.*/ if (some_calculation(3,20) = 40) { }
Sehen Sie, was ich falsch gemacht habe? Dieser Code ist absolut korrekt und sollte kompiliert werden. Das Problem ist, dass der Compiler nicht verstanden hat, dass Sie vergleichen möchten, anstatt den Wert zuzuweisen
40
.Mit einem
const
Rückgabewert wird das obige Beispiel nicht kompiliert. Zumindest, wenn der Compiler dasconst
Schlüsselwort nicht verwirft .quelle
some_calculation
ist ein Wert vom Typ int. Sie können keine Werte vom Typ Nichtklasse zuweisen.const
ist er korrekt und generiert keine Warnung.==