Ich mache ein paar Experimente mit dem Neuen _Generic
Stichwort und bin auf einen Sonderfall bei Mehrfachauswertungen gestoßen. Siehe Folgendes:
#include <stdio.h>
#define write_char(c) _Generic(c, char: putchar, const char: putchar)(c)
int main(void)
{
const char *s = "foo";
write_char(*s++);
write_char(*s++);
write_char(*s++);
putchar('\n');
}
Dies lässt sich gut kompilieren und erzeugt mit GCC das erwartete Ergebnis:
$ gcc -std=c11 -Wall plusplus.c -o plusplus
$ ./plusplus
foo
Auf der anderen Seite gibt Clang eine große Hupenwarnung aus:
$ clang -std=c11 plusplus.c -o plusplus
plusplus.c:9:18: warning: multiple unsequenced modifications to 's'
[-Wunsequenced]
write_char(*s++);
^~
plusplus.c:3:32: note: expanded from macro 'write_char'
#define write_char(c) _Generic(c, char: putchar, const char: putchar)(c)
...
Das Ergebnis ist aber wie erwartet:
$ ./plusplus
foo
Ich überprüfte der Normentwurfdie (auf S. 97 des PDFs) sagt:
Der steuernde Ausdruck einer generischen Auswahl wird nicht ausgewertet.
Dies scheint genau das Problem der Seiteneffekte in Makros zu adressieren (z. B. MIN
und MAX
).
Kann ich jetzt Clangs Warnung ignorieren, oder irre ich mich?
Klingt so, als sollten Sie dem Clang-Entwicklungsteam ein Problem melden, anstatt es zu ignorieren. Möglicherweise sind Sie der Erste, der auf das Problem gestoßen ist. Was passiert, wenn Sie schreiben
putchar(*s++)
? Erzeugt das auch die Warnung? Vermutlich nicht.– Jonathan Leffler
20. Dezember 2014 um 20:31 Uhr
Ich glaube, Sie haben einen Fehler in Clang entdeckt!
– Hacken
20. Dezember 2014 um 20:32 Uhr
@PascalCuoq, nein, es ist nicht verwandt. Die dort erfolgte Warnung war berechtigt. Hier ist es nicht, es gibt keine unsequenzierten Bewertungen von
++
im angegebenen Code.– Jens Gustedt
20. Dezember 2014 um 20:46 Uhr
@doukremt, ich weiß nicht, ob Sie den Fehler bereits gemeldet haben (sehe ihn nicht im Fehler-Tracker), aber nachdem ich Ihr Beispiel ausprobiert und keine Fehler gesehen habe, habe ich den Commit-Verlauf in Clang durchgesehen und gefunden dieses Bekenntnis vom 3. Dezember 2014. Es war also eigentlich ein Fehler, und er ist bereits behoben.
– xaizek
7. Februar 2015 um 14:41 Uhr
@xaizek Als Referenz für zukünftige Leser können Sie dies als die richtige Antwort auf die Frage posten.
– Ludin
5. März 2015 um 16:11 Uhr