2009-03-31 9 views
5

Ich war gerade durch die Man-Seite für printf und etwas fiel mir auf. Ich habe mich gefragt, ob es hier "Sprachanwälte" gibt, die eine relativ einfache Frage beantworten könnten :-P.frage über inkompatible printf-format spezifizierer

So ist das 'T' Modifikator ist definiert als

A folgende ganzzahlige Umwandlung mit einem ptrdiff_t Argumente entspricht.

Was ist soll passieren, wenn Sie diese mit einem unsigned integer Umwandlung kombinieren? Offensichtlich sind o, u, x und X alle als vorzeichenlose Werte zu interpretieren, während d und i signiert sind.

Ebenso gibt es mit/ohne Vorzeichen Versionen für alle Modifikatoren (int/unsigned int, size_t/ssize_t usw.) außer ptrdiff_t.

In der Praxis passiert nichts Schlimmes, da nicht signierte Versionen von Typen den gleichen Speicherplatz beanspruchen wie die signierten Versionen. Also werden die richtigen Bytes von dem Stapel entfernt.

Also nichts "schlecht" geschieht in der Tat, in den Drucken den erwarteten Wert für alle getesteten Dinge mit Ausnahme der "INT_MIN" (unter der Annahme, dass sizeof(int) == sizeof(ptrdiff_t).

printf("%tu %td\n", INT_MIN, INT_MIN); 

druckt

2147483648 -2147483648 

auf einem 32-Bit-System

Hat der Standard irgendeine Meinung dazu? Ich denke, die Antwort wird "undefined Verhalten." Aber ich dachte, ich würde fragen;).

+0

Enthält diese haben irgendetwas mit C++ zu tun (zumindest vor C++ 0x)? Wird printf() usw. in C++ 0x geändert, um mit C99 übereinzustimmen? Ich denke, du solltest das C++ - Tag entfernen. –

+0

ptrdiff_t ist in Cstddef in C++ definiert. printf existiert offensichtlich auch in C++. Ich bin mir nicht bewusst, dass C++ 0x printf überhaupt ändert. –

+0

Hrmm, scheint, dass C++ nicht den c99 't' Modifikator haben kann. Meinetwegen. –

Antwort

3

Nichts zu sehen hier. Der Code, den Sie geschrieben haben, ist legal.

nur einige Fakten, warum:

  • alle signierten Integer-Typen haben unsigned Kollegen, mit den gleichen Größe/Ausrichtungsanforderungen
  • ptrdiff_t vorgeschrieben ist ein signierter Integer-Typ durch die Norm zu sein. Daher hat es einen vorzeichenlosen Zwilling. (In der Tat ähnliche Logik gilt für size_t als auch - ssize_t nicht C, aber POSIX)
  • die t Längenangabe muss arbeiten mit d, i, o, u, x, X Typen
+0

Was ist das gültige vorzeichenlose Äquivalent zu ptrdiff_t? – user83255

+0

Es hat keinen speziellen Namen - man kann nur sagen, wenn ptrdiff_t "lang lang" ist, dann ist sein vorzeichenloses Gegenstück "unsigned long long" usw. – jpalecek

+0

Die wichtige Tatsache, die Sie weggelassen haben, besteht darin, dass in Fällen, in denen der Wert sowohl in die vorzeichenbehafteten als auch in vorzeichenlosen Varianten eines Integertyps passt, dieselbe Darstellung vorhanden ist und der Standard explizit die Übergabe des "falschen" Argumenttyps zulässt ist nur für Funktionen ohne Prototypen und Variadic Funktionen möglich). Soweit ich das beurteilen kann, wäre es UB, einen negativen 'ptrdiff_t'-Wert zu übergeben, wenn der Formatspezifizierer einen vorzeichenlosen Typ erwartet. –