Ich verstehe, dass wenn ein temporäres an ein Referenzelement in der Initialisierungsliste des Konstruktors gebunden wird, das Objekt zerstört wird, wie der Konstruktor zurückgibt.Falsche Warnung über temporäre Bindung an Referenzelement im Konstruktor
jedoch Betrachten Sie den folgenden Code:
#include <functional>
#include <iostream>
using callback_func = std::function<int(void)>;
int
func(const callback_func& callback)
{
struct wrapper
{
const callback_func& w_cb;
wrapper(const callback_func& cb) : w_cb {cb} { }
int call() { return this->w_cb() + this->w_cb(); }
};
wrapper wrp {callback};
return wrp.call();
}
int
main()
{
std::cout << func([](){ return 21; }) << std::endl;
return 0;
}
Das sieht mir vollkommen gültig. Das callback
-Objekt wird während der gesamten Ausführung der func
-Funktion und keine temporäre Kopie sollte für wrapper
-Konstruktor vorgenommen werden.
In der Tat, GCC 4.9.0 kompiliert in Ordnung mit allen Warnungen aktiviert.
jedoch GCC 4.8.2 Compiler gibt mir die folgende Warnung:
$ g++ -std=c++11 -W main.cpp
main.cpp: In constructor ‘func(const callback_func&)::wrapper::wrapper(const callback_func&)’:
main.cpp:12:48: warning: a temporary bound to ‘func(const callback_func&)::wrapper::w_cb’ only persists until the constructor exits [-Wextra]
wrapper(const callback_func& cb) : w_cb {cb} { }
^
Ist das eine falsch positive oder bin ich Missverständnis die Objektlebensdauern?
Hier sind meine genaue Compiler-Versionen getestet:
$ g++ --version
g++ (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ --version
g++ (GCC) 4.9.0 20140604 (prerelease)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Deaktivieren von Optimierungen gibt mir einen Seg Fehler. Valgrind weist darauf hin, dass das Problem irgendwo bei 'func (std :: function const &) :: wrapper :: call()' liegt. –
Die Verwendung von 'w_cb {cb}' führt zu einer Segmentierungsverletzung für mich. Die Verwendung von 'w_cb (cb)' leidet nicht unter dem gleichen Problem. Getestet in g ++ 4.8.3. –
Ich könnte den Valgrind-Fehler mit GCC 4.8.2 reproduzieren. (Kein segfault, zäh, das Programm gibt 42 aus und wird wie erwartet erfolgreich beendet.) Die von GCC 4.9.0 erzeugte ausführbare Datei ist Valgrind-clean. Diese Beobachtungen ändern sich nicht mit verschiedenen Optimierungsstufen. – 5gon12eder