Ich war der in this earlier question, da Code mit Blick auf die Code enthalten, die im Wesentlichen die folgende ist:Warum gibt g ++ keine Warnungen aus, wenn uninitalisierte Werte durch const-Referenz in Funktionen übergeben werden?
bool (*uninitializedFunctionPointer)(int, int);
typedef std::multimap<int, std::string, bool(*)(int, int)> MultiMapType;
MultiMapType myMap(uninitializedFunctionPointer);
Beachten Sie, dass (wie der Name schon sagt) uninitializedFunctionPointer
ist ein uninitlized Funktionszeiger, der in den Konstruktor von myMap
übergeben wird. Seltsamerweise, wenn ich diesen Code mit g ++ 4.8.4 mit -Wall -Werror
kompilierte, kompilierte es diesen Code, ohne irgendwelche Warnungen zu melden. Aber es tat Bericht ein Fehler für diesen ähnlichen Code:
bool (*uninitializedFunctionPointer)(int, int);
uninitializedFunctionPointer(137, 42);
Da die Funktionszeiger ruft eine Warnung ausgelöst, aber es in den multimap
Konstruktor nicht, ich dachte, dass g ++ einfach nicht über die Weitergabe scherte nicht initialisierte Werte als Parameter für Funktionen. Allerdings ist dieser Code in der Tat eine Warnung auslösen:
void doSomething(bool (*function)(int, int)) {
function(137, 42); // Problem if 'function' is uninitialized
}
bool (*uninitializedFunctionPointer)(int, int);
doSomething(uninitializedFunctionPointer); // Warning!
ich zum cppreference documentation for multimap
ging und sah, dass der multimap
Konstruktor in seinem Komparator durch konstante Referenz nimmt, so habe ich versucht, diesen Code zu schreiben:
typedef bool (*FunctionType)(int, int);
void doSomething(const FunctionType &function) {
function(137, 42); // Problem if 'function' is uninitialized
}
bool (*uninitializedFunctionPointer)(int, int);
doSomething(uninitializedFunctionPointer);
Und, überraschenderweise, dieser Code kompiliert vollständig gut ohne Warnungen überhaupt. Ich dachte, dass dies etwas mit Funktionszeigern zu tun haben könnte, aber es sieht so aus, als wäre das nicht der Fall! Hier ist im Zusammenhang Code, der einfach nur alte ganzen Zahlen verwendet:
void doSomething(const int &value) {
std::cout << value << std::endl; // Problem if value is uninitialized
}
int uninitializedInt;
doSomething(uninitializedInt);
Dieser Code kompiliert ohne Warnungen an alle, auch mit -Wall
aktiviert.
Ich verstehe, dass der Compiler nicht Warnungen für alle Arten von Programmierfehlern ausgeben muss, aber es scheint sehr ungewöhnlich, dass g ++ eine direkte Verwendung einer nicht initialisierten Variable und einen Versuch, eine nicht initialisierte Variable in eine Funktion übergeben würde nach Wert, würde jedoch kein Problem melden, wenn eine nicht initialisierte Variable in eine Funktion by const reference übergeben wird.
Gibt es einen zwingenden Grund, warum g ++ hier keine Warnung meldet? Wie in, gibt es vernünftigen Code, wo eine nicht initialisierte Variable in eine Funktion durch const Referenz übergeben werden könnte, ohne irgendeine Art von undefiniertem Verhalten auszulösen? Oder ist das nur ein Versehen im Compiler?
Die Funktion konnte einen Verweis oder Zeiger auf die nicht initialisierte Variable * speichern * und dann ihren Wert später lesen, nachdem sie initialisiert wurde. Ich würde dies zu einer Antwort machen, außer dass ich mir kein spezifisches Beispiel von oben vorstellen kann. Aber ich vermute, es ist üblich genug, so dass Warnung in diesem Fall Lärm wäre. – Brian
@Brian: Der gesamte CRTP-Code hängt von dieser Funktionalität ab. –
@MooingDuck Verwendet CRTP das tatsächlich? Es verwendet Vorwärtsdeklarationen von Typen, aber das ist im Typsystem und nicht in Laufzeitvariablen. – templatetypedef