Warum stimmen Argumente nicht mit dem Konvertierungsspezifizierer in printf undefiniertem Verhalten überein?

Sowohl in C (n1570 7.21.6.1/10) als auch in C ++ (durch Einbeziehung der C-Standardbibliothek) ist es undefiniert, printf ein Argument bereitzustellen, dessen Typ nicht der Konvertierungsspezifikation entspricht. Ein einfaches Beispiel:

printf("%d", 1.9)

Die Formatzeichenfolge gibt einen int an, während das Argument ein Gleitkommatyp ist.

Diese Frage ist inspiriert von der Frage eines Benutzers, der auf alten Code mit einer Fülle von Conversion-Mismatches gestoßen ist, die anscheinend keinen Schaden angerichtet haben, vgl.undefiniertes Verhalten in Theorie und Praxis.

Deklarieren einer bloßen Formatinkongruenz von UB erscheint zunächst drastisch. Es ist klar, dass dasAusgab kann falsch sein, abhängig von Dingen wie der exakten Nichtübereinstimmung, Argumenttypen, Endianness, möglicherweise Stack-Layout und anderen Problemen. Dies erstreckt sich, wie ein Kommentator hervorhob, auch auf nachfolgende (oder sogar frühere?) Argumente. Aber das ist alles andere als allgemein UB. Persönlich bin ich nie auf etwas anderes gestoßen als auf die erwartete falsche Ausgabe.

Um eine Vermutung zu wagen, würde ich Ausrichtungsprobleme ausschließen. Was ich mir vorstellen kann, ist, dass das Bereitstellen einer Formatzeichenfolge, die printf große Daten zusammen mit kleinen tatsächlichen Argumenten erwarten lässt, möglicherweiseprintf Lesen Sie über den Stapel hinaus, aber mir fehlen tiefere Einblicke in den var args-Mechanismus und spezifische printf-Implementierungsdetails, um dies zu überprüfen.

Ich hatte einen kurzen Blick auf dieprintf sources, aber sie sind für den Gelegenheitsleser ziemlich undurchsichtig.

Daher meine Frage: Was sind die spezifischen Gefahren der falschen Zuordnung von Konvertierungsspezifizierern und -argumenten inprintf was macht es UB?

Antworten auf die Frage(10)

Ihre Antwort auf die Frage