Clang, C++11 und die Sache mit den Fehlermeldungen

von Hubert Schmid vom 2012-08-19

Nach langer Zeit habe ich mir diese Woche mal wieder die Unterstützung für C++11 in Clang angeschaut. Die Version 3.1 unterstützt nun praktisch alle von mir genutzten Features. Damit ist Clang weitgehend auf dem gleichen Stand wie GCC‑4.7. An einigen Stellen musste ich zwar meinen Code anpassen. Das liegt allerdings in erster Linie an der statischen Code-Analyse und den in diesem Zusammenhang zusätzlich ausgegebenen Warnungen.

Enttäuscht war ich hingegen von den ersten Fehlermeldungen. Denn schließlich soll in deren Qualität ja einer der großen Vorteile von Clang gegenüber GCC liegen.

$ clang++ -std=c++11 test.cpp test.cpp:10:5: error: cannot initialize object parameter of \ type 'foo' with an expression of type 'foo' f.bar(); ^ test.cpp:11:5: error: cannot initialize object parameter of \ type 'foo' with an expression of type 'foo' foo{}.baz(); ^ 2 errors generated.

Demnach ist das Problem also, dass an zwei Stellen ein Parameter vom Typ foo nicht mit einem Ausdruck vom Typ foo initialisiert werden kann. Das liest sich merkwürdig und sieht nicht wirklich wie eine Verbesserung gegenüber GCC aus.

Recht hat er zumindest damit, dass diese beiden Stellen fehlerhaft sind, und dass es irgendetwas mit dem Typ foo und einem Parameter zu tun hat. Der zugehörige Code sieht wie folgt aus:

struct foo { void bar() && { } void baz() & { } }; int main() { foo f; f.bar(); foo{}.baz(); }

Das Problem an der Fehlermeldung ist, dass Clang nicht präzise genug ist und an dieser Stelle nicht zwischen L‑Value und R‑Value unterscheidet. Ich würde sogar behaupten, dass GCC‑4.7 in diesem Fall eine deutlichere Fehlermeldung ausgibt. Das scheitert allerdings bereits daran, dass dort R‑Value references for *this bisher überhaupt nicht unterstützt werden, und der Übersetzer über die neue Syntax stolpert, wie man an folgender Ausgabe sieht:

$ gcc -std=c++11 test.cpp test.cpp:3:14: error: expected ‘;’ at end of member declaration test.cpp:3:19: error: expected unqualified-id before ‘{’ token test.cpp:3:21: error: expected ‘;’ at end of member declaration test.cpp:4:14: error: expected ‘;’ at end of member declaration test.cpp:4:18: error: expected unqualified-id before ‘{’ token test.cpp:4:20: error: expected ‘;’ at end of member declaration

Das muss man Clang zu Gute halten. Leider bleibt ein kleiner Nachgeschmack: Der erste Eindruck hätte besser sein können.