Stellen finden wo Returnwert an const-ref gebunden wird
-
Das Build System ist Visual Studio 2017, Toolchain ist Visual Studio 2015.
google google ... Es scheint eine Projekteigenschaft zu geben, die "ContinueOnError" heißt. Wie du die auf true kriegst, musst du selber raustüfteln. Ich hab hier nur Linux.
Und die alle manuell zu checken ob mit dem Ergebnis ne Reference initialisiert wird ...
Vermutlich würde ich versuchen, diese Stellen mit ner Regex zu finden, irgendwas wie "const&BLA=BLUBB.value()". Viel Handarbeit bleibts trotzdem.
Das ist übrigens einer der Gründe, warum dieser T-Operator große Kacke ist und dringend entfernt gehört: Kaum möglich, nach sowas im Code zu suchen
Ich glaub du hast überhaupt nicht verstanden worum es geht.
Vielleicht. Trotzdem gern geschehn.
-
Kannst du das nicht mit der Suchfunktion und etwas Regex lösen? Wird natürlich recht aufwendig, wenn du alle Sonderfälle abdecken willst. Aber ansonsten müsste es doch irgendetwas in diese Richtung sein:
/Bar\s+const&\s+[a-zA-Z][a-zA-Z0-9]*\s*=\s*[a-zA-Z][a-zA-Z0-9]*\.value\(\)/
Leider sind alle meine Ideen, um das über Code zu lösen/finden bisher gescheitert.
-
Müsste man das nicht über ein Plugin für clang tidy machen können?
Und ich würde Klassen nicht Foo nennen, das sieht echt unprofessionell aus
-
Mechanics schrieb:
Müsste man das nicht über ein Plugin für clang tidy machen können?
Und ich würde Klassen nicht Foo nennen, das sieht echt unprofessionell aus
Wie sonst? Das deutsche 08/15 geht nicht, kein Buchstabe/Unterstrich am Anfang, Operator im Bezeichner
*duckundweg*
-
@Dravere
Das könnte ich probieren wenn ...
- da nicht der elendigeoperator T const&
wäre über den geschätzt 80% der Zugriffe erfolgen
- wir nicht zig andere Funktionen in anderen Klassen hätten dievalue
heissenUnd natürlich wäre das nicht sicher, denn die Regex "übersieht" ja einiges (Referenz-Typ als blah::const_reference, Zuweisungen mit Zeilenumbruch drin usw.). Wobei das noch gerade "OK" wäre, 100%ige Sicherheit wäre zwar schön, aber nicht unbedingt erforderlich.
Dravere schrieb:
Leider sind alle meine Ideen, um das über Code zu lösen/finden bisher gescheitert.
Meine leider auch, weswegen ich hier frag(t)e
-
Also soweit ich verstehe, handelt es sich um Stellen, in denen das
Foo<T>
an eine ReferenzT const&
gebunden wird?operator T() ; operator T const&() volatile = delete;
Es wird der zweite Operator ausgewählt, wenn wir eine Referenz binden, siehe [dcl.init.ref]/(5.1.2). Sonst wird der andere mangels
volatile
präferiert. Demo.Der obige Code ist auch sicher in dem Sinne, dass
volatile
Objekte trotzdem einen Fehler generieren, es gibt also eine false negatives.Edit: Ich denke, ähnliches kann man für
value()
Aufrufe anwenden, wennvalue
stattdessen einen Proxy zurückgibt, der wiederum den obigen Trick einsetzt.
-
Arcoth, danke!!!
Einself!Ich kannte die genauen Regeln dafür nichtmal, da wäre ich im Leben nicht draufgekommen.
-
Hachja, wäre schön gewesen, geht bloss leider nicht, weil halt auch sowas vorkommt:
#include <string> struct A { operator std::string() const; operator std::string const&() const volatile = delete; }; int main() { A a; std::string b1 = a; b1 = a; // use of deleted function operator std::string const& }
Trotzdem nochmal danke!
-
hustbaer schrieb:
Ich will Stellen finden wo
Bar const& b = foo.value(); // ODER Bar const& b = foo;
steht (weil das übel wäre)
Das ist eigentlich nur übel, wenn
foo
sehr kurzlebig ist und mit Abschluss dieser Zeile wieder zerstört wird. Denn dann hättest Du eine baumelnde Referenzb
. Geht es darum, das zu vermeiden?Wenn Du die Methode so anpasst, dass es das Bar "by value" zurück gibt, wäre die Sache mit der Referenz
b
kein Problem mehr. Dafür gibt es eine Regel im Standard, die die Lebenszeit eines temporären Objekts verlängern kann. Siehe https://herbsutter.com/2008/01/01/gotw-88-a-candidate-for-the-most-important-const/Vielleicht kann man generell so ein Static Analyzer anpassen, um solche Stellen zu finden. Google hat ja auch automatisiert solche Situationen
void sink(string const&); void bar(string const& x) { sink(x.c_str()); }
gefunden, wo eine unnötige Konvertierung (string -> c_str -> string) stattfindet. Ich finde aber die Information, wie sie das genau gemacht haben, nicht mehr. Ich würde mir mal clang-tidy angucken, um zu schauen, wie einfach es ist, den so anzupassen, dass er die gewünschten Stellen für Dich findet.
-
Nein, darum geht's nicht. Worum es geht steht dagegen im Kopfbeitrag.