Es geht darum chars als Hexzahlen darzustellen.
Ich frage mich ob folgendes erlaubt ist:
#include <stdio.h>
int main()
{
char a = -100;
printf("number: %x \n", (unsigned char) c);
}
Oder muss ich hier noch zusätzlich noch auf unsigned int casten?
mfg
Christoph
> Es geht darum chars als Hexzahlen darzustellen.
> Ich frage mich ob folgendes erlaubt ist:
>
> #include <stdio.h>
> int main()
> {
> char a = -100;
> printf("number: %x \n", (unsigned char) c);
a oder c? ;-)
> }
>
> Oder muss ich hier noch zusätzlich noch auf unsigned int casten?
(unsigned char)c wird höchstwahrscheinlich zu int promoted.
%x erwarted unsigned, also wirst Du um den cast nicht herumkommen.
oder:
unsigned b = (unsigned char)a;
printf("%x\n", b);
Jirka
Wird in aller Regel so gehen, aber strenggenommen musst du zusaetzlich
auf 'unsigned int' casten.
Der Grund ist, dass '(unsigned char)c' fast ueberall (ausser auf
Rechnern wo sizeof(int)==1 ist) als 'int' uebergeben wird, %x aber einen
'unsigned int' erwartet, und wenn der Typ nicht passt gibt es 'undefined
behaviour'. Im wirklichen Leben klappt's aber dennoch (habe nie von
einem Fall gehoert wo's nicht ginge), weil die Darstellung der 'unsigned
char' als 'int' derjenigen gleicht, die als 'unsigned int' vorlaege.
Besser ist IMHO, man macht den zusaetzlichen Cast.
Hoppla ;-)
>> Oder muss ich hier noch zusätzlich noch auf unsigned int casten?
>
> (unsigned char)c wird höchstwahrscheinlich zu int promoted.
> %x erwarted unsigned, also wirst Du um den cast nicht herumkommen.
Ich dachte, das hier eher die verschiedene Größe von char und int zu
einem Problem führen könnte. Ich meine, ich gebe einen unsigned char an
die Ellipsis und dort wird aber ein unsigned int erwartet. Irgendwie
hatte ich ein mulmiges Gefühl dabei...
Aber ich werde einfach das ganze durch deinen Vorschlag ersetzen...
thx,
Christoph
> Ich frage mich ob folgendes erlaubt ist:
>
> #include <stdio.h>
> int main()
> {
> char a = -100;
Das klappt nur, wenn Deine C-Implementierung char als signed char darstellt.
> printf("number: %x \n", (unsigned char) c);
> }
>
> Oder muss ich hier noch zusätzlich noch auf unsigned int casten?
Solltest Du auf jeden Fall tun.
Wenn sizeof(int) == 1 ist, wird der Wert automatisch als unsigned int
übergeben. Ist jedoch sizeof(int) > 1, würde ein (signed) int daraus.
"%x" erwartet aber in jedem Fall ein unsigned int.
Gruß. Claus
Wieso? Wenn char unsigned ist, sollte 156 rauskommen (bei CHAR_BIT == 8).
Jirka
> Claus Reibenstein wrote:
>
>>Christoph Rabel schrieb:
>
>>> char a = -100;
>>
>>Das klappt nur, wenn Deine C-Implementierung char als signed char darstellt.
>
> Wieso? Wenn char unsigned ist, sollte 156 rauskommen (bei CHAR_BIT == 8).
Wer sagt das? Der Standard? Wo genau?
Gruß. Claus
In 6.3.1.3: "Otherwise, if the new type is unsigned, the value is
converted by repeatedly adding or subtracting one more than the maximum
value that can be represented in the new type until the value is in the
range of the new type."
Da -100+256==156 wird eben dieser Wert gespeichert.
>#include <stdio.h>
>int main()
>{
> char a = -100;
> printf("number: %x \n", (unsigned char) c);
>}
>... muss ich hier noch zusätzlich noch auf unsigned int casten?
Im Gegensatz zur bisher kultivierten und unisonen Meinung - muss man
nicht. Weil:
Entweder koennen nicht alle Werte, die ein `unsigned char' annehmen
kann, in einem `int' untergebracht werden - dann wird obiger `unsigned
char'-Wert eh nach `unsigned int' promotet.
Sonst und normalerweise wird er bekanntlich nach `int' gewandelt. Der
Witz hier ist, dass das ein positives `int' ist, oder anders gesagt:
Das Sign-Bit ist 0. Jedes (Value-)Bit in der Repraesentationen solcher
`int's aber entspricht dem gleichen Bit des selben Wertes in der
Repraesentation eines `unsigned int'. D.h. man kann die `int'-Reprae-
sentation eines positiven Wertes als `unsigned int' lesen und erhaelt
den selben Wert. Alles 6.2.6.2p2. Auch in diesem Fall ist also kein
Cast noetig.
b.
Das ist ein unstrittiger Fall.
> Sonst und normalerweise wird er bekanntlich nach `int' gewandelt. Der
> Witz hier ist, dass das ein positives `int' ist, oder anders gesagt:
> Das Sign-Bit ist 0. Jedes (Value-)Bit in der Repraesentationen solcher
> `int's aber entspricht dem gleichen Bit des selben Wertes in der
> Repraesentation eines `unsigned int'. D.h. man kann die `int'-Reprae-
> sentation eines positiven Wertes als `unsigned int' lesen und erhaelt
> den selben Wert. Alles 6.2.6.2p2. Auch in diesem Fall ist also kein
> Cast noetig.
Die Problematik war vor kurzem in einem anderen Thread bereits dran,
daher hier nur in Kuerze:
Die Repraesentation ist unstrittig diejenige eines legalen 'unsigned
int' mit demselben arithmetischen Wert und kann deshalb problemlos
verarbeitet werden (und wird es auch auf quasi allen Plattformen), aber
der Typ ist halt immer noch 'int', und printf() darf wissen dass der Typ
nicht passt weil printf() Teil der Implementation ist. Zugegebenermassen
gehoert dazu ein gewisses Mass an krimineller Energie seitens des
printf()-Implementierers, aber es ist erlaubt, dass printf() hier
undefined behaviour ausloest.
Z.B. koennte bereits der Compiler sich weigern dies zu uebersetzen und
eine Fehlermeldung "type mismatch" ausgeben, oder printf() koennte eine
solche Ausgabe zur Laufzeit machen und das Programm beenden.
In diesem Fall wäre es ratsam, dieser Firma nie wieder irgendetwas
abzukaufen, was komplizierter ist, als ein Überraschungsei und einem
anderen Zweck dienen soll.
Man muß natürlich gar nichts. Aber: %x fordert unsigned, warum also
nicht auch unsigned liefern? Warum willst Du sowas wie
int i = 42;
printf("%u\n", i);
unterstützen? Darüberhinaus besteht die theoretische, wenn auch
unwahrscheinliche, Möglichkeit, daß int und unsigned in verschiedenen
Registern übergeben werden.
Jirka
Weil es sinnvoll ist (... und man es für va_* ohnehin braucht)?
Die Implementierung waere in diesem Fall zwar eher "ungewoehnlich"
aber noch immer standardkonform (im Gegensatz zu diesem Programm) ...
Der Fehler laege eindeutig beim Programmierer, nicht beim Hersteller
des Compilers (und wenn es auch ohne cast auf "unsigned int" funk-
tioniert, ist es genau genommen eher Zufall). Ich weiss, dass du
da anderer Meinung zu sein pflegst, aber deine Einstellung in sol-
chen Faellen aehnelt der Einstellung der Leute, die (dank unportablem
Code) zu den massenhaften Problemen beim Umstieg von gcc-2.95.x auf
gcc-3.xx gesorgt haben: Es funktionierte vieles nicht mehr, weil
sich die Leute auf Eigenschaften des Compilers verlassen haben, die
der Standard nicht garantiert, die aber "bisher immer so waren"
und die dann eben irgendwann mal nicht mehr funktionierten ...
Tschuess,
Juergen Ilse (jue...@usenet-verwaltung.de)
--
Das Netz ist Freude. Es ist Ekstase, die jeden einzelnen Nerv erglühen
läßt. Es ist Duft, den man fühlt. Es ist ein Bild, das man riecht.
Es ist Erfüllung - ein Geschmack, neben dem alles andere schal ist.
("Netzreiter-Preisung" aus dem Buch "Der Netzparasit" von Andreas Brandhorst)
>Bernd Luevelsmeyer <bdlu...@heitec.net> writes:
>> [printf(), "type mismatch", usw]
>
> In diesem Fall wäre es ratsam, dieser Firma nie wieder irgendetwas
> abzukaufen, was komplizierter ist, als ein Überraschungsei und einem
> anderen Zweck dienen soll.
Nunja, vielleicht magst Du so denken, ich jedenfalls bin froh, wann immer
mein GCC mir mitteilt, daß ich falsche Argumente an printf & CO übergeben
habe. YMMV.
Gruß, Bodo
--
MS Outlook Express?->[DE: http://piology.org/ILOVEYOU-Signature-FAQ.html]
@@@@@ GEGEN TCG aka. TCPA: @@@@@ [DE: http://www.againsttcpa.com]
Dies:
unsigned u = 42;
printf("%u\n", u);
und dies:
int i = 42;
printf("%i\n", i);
ist sinnvoll. Warum also nicht richtig machen?
>(... und man es für va_* ohnehin braucht)?
Wenn Du sowas für va_* brauchst, machst Du irgendetwas falsch.
[...]
>> In diesem Fall wäre es ratsam, dieser Firma nie wieder irgendetwas
>> abzukaufen, was komplizierter ist, als ein Überraschungsei und einem
>> anderen Zweck dienen soll.
>
> Die Implementierung waere in diesem Fall zwar eher "ungewoehnlich"
> aber noch immer standardkonform (im Gegensatz zu diesem Programm)
> ...
Sie wäre das nicht. '42' ist ein Wert, der 'by value' genauso an eine
Funktion übergeben wird, wie ein int (read: Maschinenwort) und das war
es dann. Falls ich -42 übergebe, legt der Standard nicht fest, wie das
resultierende Bitmuster aussieht, deswegen ist seine Interpretation
als vorzeichenloser integer nicht durch ISO vorgegeben und das war es
diesbezüglich. Zuweisungskompatibel sind sie beide trotzdem und wer
Variablen und Werte nicht auseinanderhalten kann, ist hier (um die
Perl-Dokumentation zu zitieren) 'victim of metaphor clash'.
> Der Fehler laege eindeutig beim Programmierer, nicht beim Hersteller
> des Compilers (und wenn es auch ohne cast auf "unsigned int" funk-
> tioniert, ist es genau genommen eher Zufall).
'In der Praxis' ist es abschreckend egal, wer die Schuld hat, sondern
da findet man heraus, was der Compiler anderes tut, als er tun sollte
und behilft sich mit versionsspezifischen workarounds. Das ist sehr
unschön, denn dadurch wird der Code leider unportabel, was nicht sein
müßte, aber es leider unpraktikabel, sich nur deswegen erstmal einen
Compiler zu schreiben, weil der praktischerweise Maschinencode
nachvollziehbar anhand portabler Beschreibungen generiert, und zwar
den, den man ihn generieren lassen wollte.
> Ich weiss, dass du da anderer Meinung zu sein pflegst, aber deine
> Einstellung in solchen Faellen aehnelt der Einstellung der Leute,
> die (dank unportablem Code) zu den massenhaften Problemen beim
> Umstieg von gcc-2.95.x auf gcc-3.xx gesorgt haben: Es funktionierte
> vieles nicht mehr, weil sich die Leute auf Eigenschaften des
> Compilers verlassen haben, die der Standard nicht garantiert, die
> aber "bisher immer so waren" und die dann eben irgendwann mal nicht
> mehr funktionierten ...
Siehe oben. Es funktionierte leider vieles nicht mehr, weil die ganzen
hacks, mit denen man den alten Compiler dazu nötigen konnte,
sinngetreu zu übersetzen, compilerspezifisch waren. Ergo mußten die
alle geändert werden, und die Rechnung hätte man an den Hersteller
schicken sollen, denn die mußten wegen ihm geändert werden. Wenn ich
heute eine Variable deklariere muß ich zusätzlich danebenschreiben,
daß ich auch wirklich eine Variable haben wollte, das ist analog zu
'wollen diese Datei löschen?' 'wollen sie die wirklich löschen?'
'wollen sie die echt wirklich löschen?' 'na gut, ich will aber
nicht' (vor zwei Tagen live unter Windows erlebt) und eine
schreckliche Zeitverschwendung. Ebenso wie die Tatsache, daß gcc zwar
ungefragt Variablen löscht, aber leider nicht imstande ist, Vergleiche
mit Konstanten automatisch zu Vergleichen mit Null zu übersetzen, wenn
das für eine bestimmte CPU sinnvoll wäre, und man das deswegen auch noch
wissen und von Hand machen muß.
Noch so ein schönes Geschichtchen: Ein Freund von mir ist Physiker,
und ein Freund von dem arbeitet an einem C++-Programm, an dem in sechs
Jahren sechs Personen gearbeitet haben, die ca 2000 Zeilen
Berechnungen mit ungefähr 4000 Zeilen GUI kombiniert haben,
funktionieren tut beides nicht, aber das Programm ist mittlerweile
soweit 'handoptimiert', daß es überhaupt keine Argumente mehr übergibt,
sondern nach Maßgabe einer undefinierbaren Konvention alles mit Hilfe
der globalen Variablen h, i, j, k und l macht, und um diesen Unsinn
transparent abzustellen, braucht man einen optimierenden
Compiler. Andere Leute können im Zweifelsfall gcc 2.7.3 benutzen und
der Code wird an allen Stellen, an denen das überhaupt relevant ist,
genauso schnell. No problem here. Ich habe schon mehrere
printf-Interpreter aus Langweile/ Interesse/ Neugier geschrieben und
man benutzt keine Bibliotheken, weil die Dokumentation wie immer
Hinweischarakter hat, man alle relevanten Details folglicherweise aus
den Quellen extrahieren muß, die aber jederzeit wahllos geändert
werden, und deswegen ist das zuviel Aufwand und wird
reimplementiert. Im Zweifelsfall in unbezahlten Nachtschichten, denn
bekommts keiner mit.
F'up2 poster wegen vollkommener Unrelevanz
Es sind zwei überflüssige Variablen. C übergibt Funktionsargumente 'by
value', dh der Wert von 'u' wird ausgelesen, nach 'int' promotet und
so an die Funktion übergeben. Es ist egal, wo er herkam. Die Ausgabe
von
printf("%u\n", -3);
ist durch C undefiniert, weil es drei mögliche Repräsentationen von
Vorzeichenbits gibt und es außer value bits auch noch padding bits
geben kann (nicht 'darf'). Das bedeutet nicht, daß man mit einem
beliebigen vortstellbaren Verhalten rechnen müsse, sondern bloß, daß
dieses Bitmuster für unterschiedliche CPUs unterschiedlich sein
kann und die C-Norm macht darüber weiter keine Aussage. Insbesondere
macht sie keine der Aussagen, die irgendjemand mit einer blühenden
Phantasie in diesem Leerraum anzubringen können glaubt.
>>(... und man es für va_* ohnehin braucht)?
>
> Wenn Du sowas für va_* brauchst, machst Du irgendetwas falsch.
printf ist eine Funktion, die eine variable Anzahl von Argumenten
übernimmt, in C existiert ein Mechanismus, mit dem man sowas
implentieren kann und für den wird Zuweisungskompatibilität von
vorzeichenbehafteten und vorzeichenlosen Werten ausdrücklich
gefordert (insofern der Wert als beides dargestellt werden kann).
Es wird nicht gefordert, daß printf diesen Mechanismus benutzt, aber
aus ökonomischen Gründen wird das im Allgemeinen der Fall sein und
falls nicht kann man es auf diesem Weg ersetzen.
Rainer Weikusat <weik...@students.uni-mainz.de> wrote:
> Juergen Ilse <jue...@usenet-verwaltung.de> writes:
>> Rainer Weikusat <weik...@students.uni-mainz.de> wrote:
>>> Bernd Luevelsmeyer <bdlu...@heitec.net> writes:
> [...]
>>> In diesem Fall wäre es ratsam, dieser Firma nie wieder irgendetwas
>>> abzukaufen, was komplizierter ist, als ein Überraschungsei und einem
>>> anderen Zweck dienen soll.
>> Die Implementierung waere in diesem Fall zwar eher "ungewoehnlich"
>> aber noch immer standardkonform (im Gegensatz zu diesem Programm)
>> ...
> Sie wäre das nicht.
Doch.
> '42' ist ein Wert,
Der "unsigned-Wert 42" ist etwas anderes als der "int-Wert 42",
und zwar selbst dann, wenn beide durch das selbe Bitmuster dar-
gestellt werden.
> der 'by value' genauso an eine Funktion übergeben wird, wie ein
> int (read: Maschinenwort) und das war es dann.
Wo garantiert der Standard, dass int und unsigned in der selben
Weise an Funktionen uebergeben wird? Wenn du eine solche Garantie
nicht anhand des Standards belegen kannst, ist deine Argumentation
nicht durch den Standard gedeckt und damit (in Bezug auf die
Sprache C allgemein) falsch.
> Falls ich -42 übergebe, legt der Standard nicht fest, wie das
> resultierende Bitmuster aussieht, deswegen ist seine Interpretation
> als vorzeichenloser integer nicht durch ISO vorgegeben und das war es
> diesbezüglich.
Der standard sagt exakt *gar nichts* darueber aus, ob unterschiedliche
Datentypen in der selben Form an Unterprogramme uebergeben werden
koennen oder muessen wie dandere. Das betrifft auch die Typen unsigned
und int (selbst dann, wenn dort positive Werte durch das selbe Bit-
muster dargestellt werden).
> Zuweisungskompatibel sind sie beide trotzdem und wer Variablen und
> Werte nicht auseinanderhalten kann,
Es handelt sich nicht nur um den Wert 42 (unabhaengig vom Datentyp)
sondern um den Wert 42, dessen Typ aus dem Kontext hervorgeht.
>> Der Fehler laege eindeutig beim Programmierer, nicht beim Hersteller
>> des Compilers (und wenn es auch ohne cast auf "unsigned int" funk-
>> tioniert, ist es genau genommen eher Zufall).
> 'In der Praxis' ist es abschreckend egal, wer die Schuld hat, sondern
> da findet man heraus, was der Compiler anderes tut, als er tun sollte
> und behilft sich mit versionsspezifischen workarounds.
... oder mit dem, was der Standard garantiert. Das liegt in dem
diskutierten Fall nur um einen klitzekleinen und nicht weiter
stoerenden cast auseinander.
> F'up2 poster wegen vollkommener Unrelevanz
Ignoriert, weil das Thema hier durchaus nicht irrelevant ist.
6.2.5|9, inklusive Fußnote. Es folgt außerdem indirekt aus der
Spezifikation von va_arg, daß es für benutzerdefinierte Funktionen so
sein muß.
> ... oder mit dem, was der Standard garantiert. Das liegt in dem
> diskutierten Fall nur um einen klitzekleinen und nicht weiter
> stoerenden cast auseinander.
Der Standard garantiert mir leider gar nichts, solange er von den
meisten Leuten nach Maßgabe einer Agenda¹ kreativ mißinterpretiert
oder gar nicht erst verstanden wird.
1) In diesem Fall: Den von Dennis Richtie vermutlich
wohlweislich vermieden Typen-Unfug, den 'people from
academia' betörend zu finden scheinen 'irgendwie' durch die
Hintertür doch in die Sprache hineinzubekommen. C ist in
vielen Fällen sehr angenehm zu programmieren, weil der
Compiler vernünftige (dh aus praktischer Erfahrung als
sinnvoll erkannte) Annahmen über die Intention des
Programmierers machen darf und sollte.
Naja, doch, etwas: C-Compiler, die wahllos und inkompatibel zueinander
an meinem Code Dinge zu verbessern versuchen, die gar nicht
'verbessert' werden müßten. Vermutlich muß man solche Dokumente
tatsächlich in der unleserlichen Weise, in der das ARM geschrieben
wurde, formulieren, denn die hat (einzigen) praktischen Vorteil: Sie
läßt nach Möglichkeit keinen Spielraum für Hypothesen.
Rainer Weikusat <weik...@students.uni-mainz.de> wrote:
> Juergen Ilse <jue...@usenet-verwaltung.de> writes:
>> Rainer Weikusat <weik...@students.uni-mainz.de> wrote:
>>> '42' ist ein Wert,
>> Der "unsigned-Wert 42" ist etwas anderes als der "int-Wert 42",
>> und zwar selbst dann, wenn beide durch dasselbe Bitmuster dar-
>> gestellt werden.
>>> der 'by value' genauso an eine Funktion übergeben wird, wie ein
>>> int (read: Maschinenwort) und das war es dann.
>> Wo garantiert der Standard, dass int und unsigned in derselben
>> Weise an Funktionen uebergeben wird?
> 6.2.5|9, inklusive Fußnote. Es folgt außerdem indirekt aus der
> Spezifikation von va_arg, daß es für benutzerdefinierte Funktionen so
> sein muß.
Bei variablen Argumentlisten hast du recht, aber es gab und gibt
noch immer mehr als einen Compiler, der bei variablen Argument-
listen andere Parameteruebergabe verwendet als bei festen Anzahl
und Typen der Argumente. Mit anderen Worten: bei festen Argumenten
garantiert dir niemand, dass unsigned und int gleich uebergeben
werden muessen, oder habe ich dich jetzt falsch verstanden?
Demnach ist im Falle von festen Argumentlisten mein Einwand berechtigt
und dein Argumentation falsch. Auf nichts anderes wollte ich hinaus.
Stimmt auffallend.
> Da -100+256==156 wird eben dieser Wert gespeichert.
Weil UCHAR_MAX == 255 ist.
Wieso bin ich da nicht selber drauf gekommen? Irgendwie muss ich an dem
Tag schlecht drauf gewesen sein ...
Gruß. Claus
Der Punkt ist doch, jedenfalls meiner, dass printf() eben *keine*
benutzerdefinierte Funktion ist. va_arg spielt keine Rolle, ein va_arg
kommt in der ganzen Angelegenheit nicht vor. Man braucht sich gar keine
Gedanken zu machen, wie und auf welche Art printf() an
Zusatzinformationen kommen kann, das kann es notfalls einfach per
Compiler-Magie.
> > ... oder mit dem, was der Standard garantiert. Das liegt in dem
> > diskutierten Fall nur um einen klitzekleinen und nicht weiter
> > stoerenden cast auseinander.
>
> Der Standard garantiert mir leider gar nichts, solange er von den
> meisten Leuten nach Maßgabe einer Agendaą kreativ mißinterpretiert
> oder gar nicht erst verstanden wird.
Also bitte, wenn dort eindeutig von einem geforderten 'unsigned
int'-Parameter die Rede ist und 'undefined behaviour' fuer
Typ-abweichende Parameter festgelegt ist, dann gibt's da IMHO wenig zu
interpretieren. Man kann hoechstens noch feststellen, dass so gut wie
alle Compiler einen 'signed int' nicht uebelnehmen, aber man kann nicht
behaupten dass sie dazu verpflichtet waeren.
u wird keineswegs nach int promotet, sondern es bleibt ein unsigned.
> von
>
> printf("%u\n", -3);
>
> ist durch C undefiniert, weil es drei mögliche Repräsentationen von
> Vorzeichenbits gibt und es außer value bits auch noch padding bits
> geben kann (nicht 'darf'). Das bedeutet nicht, daß man mit einem
> beliebigen vortstellbaren Verhalten rechnen müsse, sondern bloß, daß
> dieses Bitmuster für unterschiedliche CPUs unterschiedlich sein
> kann und die C-Norm macht darüber weiter keine Aussage. Insbesondere
> macht sie keine der Aussagen, die irgendjemand mit einer blühenden
> Phantasie in diesem Leerraum anzubringen können glaubt.
Also in 7.19.6.1 steht "o,u,x,X The unsigned int argument..." und
spaeter "If any argument is not the correct type for the corresponding
conversion specification, the behavior is undefined."
Wenn da ein Spielraum beabsichtigt gewesen waere, haette man es mit
Spielraum festlegen koennen. Argumentationen mit Bitmustern,
Padding-Bits und dergleichen spielen hier IMHO keine Rolle, es ist ganz
einfach so dass der Typ entweder 'unsigned int' ist oder nicht. Wenn
ausdruecklich ein Typ angegeben ist, dann kann ich einen anderen nicht
als ebenfalls "the correct type" ansehen.
> >>(... und man es für va_* ohnehin braucht)?
> >
> > Wenn Du sowas für va_* brauchst, machst Du irgendetwas falsch.
>
> printf ist eine Funktion, die eine variable Anzahl von Argumenten
> übernimmt, in C existiert ein Mechanismus, mit dem man sowas
> implentieren kann und für den wird Zuweisungskompatibilität von
> vorzeichenbehafteten und vorzeichenlosen Werten ausdrücklich
> gefordert (insofern der Wert als beides dargestellt werden kann).
> Es wird nicht gefordert, daß printf diesen Mechanismus benutzt, aber
> aus ökonomischen Gründen wird das im Allgemeinen der Fall sein und
> falls nicht kann man es auf diesem Weg ersetzen.
Natuerlich wird's das. Natuerlich wird eine C-Lib ueblicherweise soweit
moeglich ganz normal als C-Quellen geschrieben, und dann ist ein va_arg
irgendwo da drin. Es *muss* aber nicht so sein.
Zum zwoten kann der Compiler ganz einfach wissen, dass er einen Aufruf
von printf() in den Fingern hat, und diesen Aufruf besonders unter die
Lupe nehmen. Er kennt ja printf(), da es ein Teil der Implementation
ist. In dem Fall waere es ganz egal, wie printf() implementiert ist.
Er ist. Ich zitiere das nochmal wörtlich:
The range of nonnegative values of a signed integer type is a
subrange of the corresponding unsigned integer type, and the
representation of the same value in each type is the same*)
*) The same representation and alignment requirements are
meant to imply interchangebility as arguments to functions,
return values from functions, and members of unions.
Eine exception clause 'printf was meant to be writeln, nevertheless'
gibt es hingegen nicht.
Die (Deine) Behauptung lautete, unsigned u würde zu int promoted. Dazu wäre
ein Zitat wesentlich interessanter. Ob und wieviele Werte von unsigned und
signed das gleiche Bitmuster haben, ist dafür erstmal irrelevant.
Waerest du also der Meinung, folgendes sei zulaessig und muesse 19
ausgeben?
#include <stdio.h>
int main(void)
{
union un
{
int i;
unsigned u;
} n;
n.i = 19;
printf("%u\n",n.u);
return 0;
}
Was "writeln" bedeuten soll ist mir nicht klar.
Im uebrigen aendert irgendeine Austauschbarkeit fuer Subranges nichts
daran, dass
a) die Typen int und 'unsigned int' nicht dasselbe sind,
b) fuer %x ein "unsigned" und nichts anderes als Typ erlaubt ist,
c) %x im printf() bei anderen Typen "undefined behaviour" ergibt.
IMHO ist das einzeln im Standard nachzuweisen und ergibt insgesamt, dass
ein int-Argument fuer %x nicht zulaessig ist.
[...]
> Im uebrigen aendert irgendeine Austauschbarkeit fuer Subranges nichts
> daran, dass
Von der steht da oben nichts.
> a) die Typen int und 'unsigned int' nicht dasselbe sind,
> b) fuer %x ein "unsigned" und nichts anderes als Typ erlaubt ist,
> c) %x im printf() bei anderen Typen "undefined behaviour" ergibt.
>
> IMHO ist das einzeln im Standard nachzuweisen und ergibt insgesamt, dass
> ein int-Argument fuer %x nicht zulaessig ist.
Nein, denn der von mir zitierte Absatz enthält wörtlich die Aussage,
daß man ints an Funktionen die unsigned erwarten und unsigneds an
Funktionen, die int erwarten, übergeben dürfen können soll, solange
der Wert als das eine und als das andere (was im übrigen als identisch
definiert ist, dh es gibt hier nur ein Ding) repräsentierbar
ist. Es steht Dir frei, trotzdem an das Gegenteil zu glauben. Das
nennt man dann einen Irrglauben.
>Juergen Ilse <jue...@usenet-verwaltung.de> writes:
>
>> Wo garantiert der Standard, dass int und unsigned in derselben
>> Weise an Funktionen uebergeben wird?
>
> 6.2.5|9, inklusive Fußnote.
Definiert, daß (int)42 und (unsigned)42 das gleiche Bitmuster haben.
> Es folgt außerdem indirekt aus der Spezifikation von va_arg, daß es für
> benutzerdefinierte Funktionen so sein muß.
^^^^^^^^^^^^^^^^^^
Es wurde aber über printf gesprochen, und das ist keine BD-Funktion.
>> ... oder mit dem, was der Standard garantiert. Das liegt in dem
>> diskutierten Fall nur um einen klitzekleinen und nicht weiter
>> stoerenden cast auseinander.
>
> Der Standard garantiert mir leider gar nichts,
Doch, und zwar einen kleinen gemeinsamen Nenner, der noch groß genug ist,
um einerseits Hardwarenah zu programmieren, um andererseits aber von der
Hardware gerade eben so weit weg zu sein, um protable Programme schreiben
zu können.
> solange er von den meisten Leuten
wie Du?
> nach Maßgabe einer Agenda¹ kreativ mißinterpretiert oder gar nicht erst
> verstanden wird.
Was hast Du denn an der Beschreibung von printf nicht verstanden?
> 1) In diesem Fall: Den von Dennis Richtie vermutlich
> wohlweislich vermieden Typen-Unfug, den 'people from
> academia' betörend zu finden scheinen 'irgendwie' durch die
> Hintertür doch in die Sprache hineinzubekommen. C ist in
> vielen Fällen sehr angenehm zu programmieren, weil der
> Compiler vernünftige (dh aus praktischer Erfahrung als
> sinnvoll erkannte) Annahmen über die Intention des
> Programmierers machen darf und sollte.
Wie das? Bis jetzt hat mir noch jeder Informatiklehrer gesagt, daß
Programme keine Zweifel darüber aufkommen lassen dürfen, was gemeint ist,
und damit bleibt kein Spielraum für irgendwelche irrsinnigen Intentionen,
die bei mindestens 50% der Programmierer eh anders sind.
> Naja, doch, etwas: C-Compiler, die wahllos und inkompatibel zueinander
> an meinem Code Dinge zu verbessern versuchen, die gar nicht
> 'verbessert' werden müßten.
Du kannst den Optimizer ausschalten, und Du weißt auch wie. Also reg'
Dich nicht auf.
> Vermutlich muß man solche Dokumente tatsächlich in der unleserlichen
> Weise, in der das ARM geschrieben wurde, formulieren, denn die hat
> (einzigen) praktischen Vorteil: Sie läßt nach Möglichkeit keinen
> Spielraum für Hypothesen.
a = (b += a) - a;
Funktioniert mit Borland C++ 3.1 zumindest wenn mit der DoS IDE eine
DoS-exe erstellt wird. Ist jetzt jeder andere Kompiler kaputt, nur weil
er es nicht kann? Ich meine, meine Intention ist doch wohl eindeutig,
oder?
Wo willst Du die Grenze ziehen?
>> >#include <stdio.h>
>> >int main()
>> >{
>> > char a = -100;
>> > printf("number: %x \n", (unsigned char) c);
>> >}
>>
>> >... muss ich hier noch zusätzlich noch auf unsigned int casten?
>>
>> Im Gegensatz zur bisher kultivierten und unisonen Meinung - muss man
>> nicht. Weil:
>>
>> Entweder koennen nicht alle Werte, die ein `unsigned char' annehmen
>> kann, in einem `int' untergebracht werden - dann wird obiger `unsigned
>> char'-Wert eh nach `unsigned int' promotet.
>Das ist ein unstrittiger Fall.
Der Vollstaendigkeit wegen aufgefuehrt.
>> Sonst und normalerweise wird er bekanntlich nach `int' gewandelt. Der
>> Witz hier ist, dass das ein positives `int' ist, oder anders gesagt:
>> Das Sign-Bit ist 0. Jedes (Value-)Bit in der Repraesentationen solcher
>> `int's aber entspricht dem gleichen Bit des selben Wertes in der
>> Repraesentation eines `unsigned int'. D.h. man kann die `int'-Reprae-
>> sentation eines positiven Wertes als `unsigned int' lesen und erhaelt
>> den selben Wert. Alles 6.2.6.2p2. Auch in diesem Fall ist also kein
>> Cast noetig.
>Die Problematik war vor kurzem in einem anderen Thread bereits dran,
Muss ich uebersehen haben, sonst haette ich etwas dazu geschrieben.
>daher hier nur in Kuerze:
>Die Repraesentation ist unstrittig diejenige eines legalen 'unsigned
>int' mit demselben arithmetischen Wert und kann deshalb problemlos
>verarbeitet werden (und wird es auch auf quasi allen Plattformen), aber
'Tschuldigung, dass ich dazwischen rede, aber: Streiche "quasi".
>der Typ ist halt immer noch 'int', und printf() darf wissen dass der Typ
>nicht passt weil printf() Teil der Implementation ist.
Der Punkt war und ist, *dass* er passt. Die (hier unausgesprochene)
Passage des Standards, dass Parameter und Argument (nach Konversion des
1. bei Verhandensein eines Prototyps, resp. nach Promotion von beiden
bei Abwesenheit oder Ellipse) kompatible Typen sein muessen, sonst UB,
stimmt nicht bei Promotion und "one promoted type is a signed integer
type, the other promoted type is the corresponding unsigned integer
type, and the value is representable in both types". 6.5.2.2p6.
Die Beschreibung und Zusicherung, dass positive Ganzzahlenwert jedes
vorzeichenbehafteten Ganzzahltypes im korrespondierenden vorzeichen-
losen vorhanden ist und die gleiche Repraesentation hat, wird in FN 31
von 6.2.5p6 genau damit begruendet.
Wenn das uebrigens alles nicht so waere, und Du, Jirka und Juergen
(habe ich jemanden uebersehen?) in diesem Punkt und mit UB Recht
haetten, waeren zwangslaeufig fast alle C-Programme defekt. Betrachte:
for( char *s = "foo\n"; *s; s++ )
printf("%c",*s);
Ist da UB 'drin? Obwohl man bekanntlich nicht weiss, ob ein "plain
char" vorzeichenbehaftet ist, es mithin moeglich ist, dass `*s' zu
`unsigned int' promotet wird, gleichzeitig aber ein `int' erwartet
wird? 7.19.6.1p8.
>Z.B. koennte bereits der Compiler sich weigern dies zu uebersetzen und
>eine Fehlermeldung "type mismatch" ausgeben, oder printf() koennte eine
>solche Ausgabe zur Laufzeit machen und das Programm beenden.
Nope.
b.
Jirka Klaue <jkl...@ee.tu-berlin.de> writes:
>Andreas Burmester wrote:
>> Christoph Rabel <od...@hal9000.vc-graz.ac.at> writes:
>>>#include <stdio.h>
>>>int main()
>>>{
>>> char a = -100;
>>> printf("number: %x \n", (unsigned char) c);
>>>}
>>
>>>... muss ich hier noch zusätzlich noch auf unsigned int casten?
>>
>> Im Gegensatz zur bisher kultivierten und unisonen Meinung - muss man
>> nicht.
>Man muß natürlich gar nichts. Aber: %x fordert unsigned, warum also
>nicht auch unsigned liefern?
Ich haette gesagt "Weil's nicht noetig ist und schon passt." Aber:
Warum man nicht casten soll, war ja nun nicht die Frage, sondern ob man
casten *muss*. Siehe hoch, steht noch da.
> Warum willst Du sowas wie
> int i = 42;
> printf("%u\n", i);
>unterstützen?
Erstmal "unterstuetze" nicht ich das, sondern die Sprache; ich's wuerde
es allerdings und tatsaechlich genauso schreiben, weil's Code-Gebrabbel
erspart und ich ueberhaupt nicht einsehe, warum man die Sprache nicht
in und mit all ihren Feinheiten auch be-, meinetwegen auch "aus-"nutzt.
> Darüberhinaus besteht die theoretische, wenn auch
>unwahrscheinliche, Möglichkeit, daß int und unsigned in verschiedenen
>Registern übergeben werden.
1. gibt's in C keine Parameteruebergabe "in Registern", der Standard
schweigt sich da aus; wenn allerdings und 2. ein Implementeur einen
Mechanismus bastelt, der dazu fuehrt, dass obiger Code crasht, dann
gehoeren ihm Paragraphen um die Ohren gehauen.
b.
Wenn alle Integertypen gleich groß sind (sagen wir 32bit), dann
kann auch UCHAR_MAX >= INT_MAX sein, sodaß char, wenn unsigned,
nach unsigned int promoted wird. Da %c int erwartet (was nix mit
irgendwelchen Bitmustern oder Wertebereichen zu tun hat, sondern
einzig und allein mit dem Typ), is es UB.
Das ist zugegebenermaßen ein pathologischer Fall, der außerdem
Probleme bei
while ((c = getc(f)) != EOF ...
verursacht, was sicher nicht im Sinne des Erfinders ist. Jedoch
läßt der Standard diese Möglichkeit zu. Erkennbare Intention und
praktische Erfahrungen hin oder her.
Jirka
>>>>#include <stdio.h>
>>>>int main()
>>>>{
>>>> char a = -100;
>>>> printf("number: %x \n", (unsigned char) c);
>>>>}
>>>
>>>>... muss ich hier noch zusätzlich noch auf unsigned int casten?
>>>
>>>Im Gegensatz zur bisher kultivierten und unisonen Meinung - muss man
>>>nicht.
>
>>Man muß natürlich gar nichts. Aber: %x fordert unsigned, warum also
>>nicht auch unsigned liefern?
>
> Ich haette gesagt "Weil's nicht noetig ist und schon passt." Aber:
> Warum man nicht casten soll, war ja nun nicht die Frage, sondern ob man
> casten *muss*. Siehe hoch, steht noch da.
OK, dann eben ganz deutlich. Ja, man muß casten.
>>Warum willst Du sowas wie
>
>> int i = 42;
>> printf("%u\n", i);
>
>>unterstützen?
>
> Erstmal "unterstuetze" nicht ich das, sondern die Sprache; ich's wuerde
> es allerdings und tatsaechlich genauso schreiben, weil's Code-Gebrabbel
> erspart und ich ueberhaupt nicht einsehe, warum man die Sprache nicht
> in und mit all ihren Feinheiten auch be-, meinetwegen auch "aus-"nutzt.
Falls man sich irrt und den Standard falsch interpretiert?
Diese Möglichkeit solltest Du in Betracht ziehen.
>>Darüberhinaus besteht die theoretische, wenn auch
>>unwahrscheinliche, Möglichkeit, daß int und unsigned in verschiedenen
>>Registern übergeben werden.
>
> 1. gibt's in C keine Parameteruebergabe "in Registern", der Standard
> schweigt sich da aus;
Der Standard verlangt, daß %u ein unsigned übergeben wird. Wie genau,
und mit welchem Mechanismus ist völlig Wurst. Register stellen eine
Möglichkeit dar (die ich mir einfach so ausgedacht habe, was mir laut
Standard frei steht).
> wenn allerdings und 2. ein Implementeur einen
> Mechanismus bastelt, der dazu fuehrt, dass obiger Code crasht, dann
> gehoeren ihm Paragraphen um die Ohren gehauen.
Damit hast Du Recht, aber das heißt nicht, daß Du %u ein int geben darfst.
Jirka
Das ist Deine Privatinterpretation von 'correct type' und die ISO-Norm
gibt eine andere vor.
Nein. Er verlangt, daß %u der 'richtige Typ' übergeben wird. Er
verlangt weiterhin, daß für corresponding integer types
vorzeichenbehaftete und vorzeichenlose als Funktionsargumente
austauschbar sein sollen. ISO akzeptiert 'defect reports' und falls Du
der Meinung bist, daß hier für printf aus einem nichtgenannten Grund
eine Ausnahme gemacht werden sollte, dann wird es sicher möglich sein,
daß zuständige Kommittee davon zu überzeugen, falls es einen
sinnvollen Grund dafür gibt. Die Chancen sind allerdings klein, denn
sowohl ich als auch die meisten anderen Leute, die C-Programme
schreiben, sehen das wohl anders, dh diese Änderung könnte sich als
ziemlich kostspielig erweisen.
Das hatte ich doch schon vor langer Zeit anhand mehrerer Stellen
aus dem Standard bewiesen - per langem Thread.
Es hat mir eben nicht jeder geglaubt, weil, wenn ich Standard-Zeilen zeige,
sind sie 'von Schellong berührt' und folglich ausnahmsweise irrelevant.
(Außerdem wird Flamern mitunter alles geglaubt, ohne Beweise des Flamers,
dem Geflameten, mit Beweisen, jedoch nicht.)
--
Mit freundlichen Grüßen
Helmut Schellong v...@schellong.biz
www.schellong.de www.schellong.com www.schellong.biz
http://www.schellong.de/c.htm
>> for( char *s = "foo\n"; *s; s++ )
>> printf("%c",*s);
>>
>> Ist da UB 'drin? Obwohl man bekanntlich nicht weiss, ob ein "plain
>> char" vorzeichenbehaftet ist, es mithin moeglich ist, dass `*s' zu
>> `unsigned int' promotet wird, gleichzeitig aber ein `int' erwartet
>> wird? 7.19.6.1p8.
>Wenn alle Integertypen gleich groß sind (sagen wir 32bit), dann
>kann auch UCHAR_MAX >= INT_MAX sein, sodaß char, wenn unsigned,
>nach unsigned int promoted wird. Da %c int erwartet (was nix mit
>irgendwelchen Bitmustern oder Wertebereichen zu tun hat, sondern
>einzig und allein mit dem Typ), is es UB.
Merkst Du nicht selbst allmaehlich, dass Du Dich in ein Irrtums-Loch
verbuddelt hast und weiter graebst? In den beiden Zeilen stecken keine
Annahmen ueber Typ-Groessen; wenn sie trotzdem UB sein sollen, sind's
so gut wie alle C-Programme.
Du gehst auch mit keinem Wort auf mehrfach angefuehrte Passagen des
Standards ein, und hast dazu noch etwas Entscheidenes im Code oben
uebersehen: Dass die 4 auszugebenen Zeichen kleiner gleich SCHAR_MAX
sind, egal, ob plain char vorzeichenbehaftet ist oder nicht.
b.
>>>>>#include <stdio.h>
>>>>>int main()
>>>>>{
>>>>> char a = -100;
>>>>> printf("number: %x \n", (unsigned char) c);
>>>>>}
>>>>
>>>>>... muss ich hier noch zusätzlich noch auf unsigned int casten?
>>>>
>>>>Im Gegensatz zur bisher kultivierten und unisonen Meinung - muss man
>>>>nicht.
>>
>>>Man muß natürlich gar nichts. Aber: %x fordert unsigned, warum also
>>>nicht auch unsigned liefern?
>>
>> Ich haette gesagt "Weil's nicht noetig ist und schon passt." Aber:
>> Warum man nicht casten soll, war ja nun nicht die Frage, sondern ob man
>> casten *muss*. Siehe hoch, steht noch da.
>OK, dann eben ganz deutlich. Ja, man muß casten.
Behauptung wiederholt, belegt mit Fussaufstampfen.
>>>Warum willst Du sowas wie
>>
>>> int i = 42;
>>> printf("%u\n", i);
>>
>>>unterstützen?
>>
>> Erstmal "unterstuetze" nicht ich das, sondern die Sprache; ich's wuerde
>> es allerdings und tatsaechlich genauso schreiben, weil's Code-Gebrabbel
>> erspart und ich ueberhaupt nicht einsehe, warum man die Sprache nicht
>> in und mit all ihren Feinheiten auch be-, meinetwegen auch "aus-"nutzt.
>Falls man sich irrt und den Standard falsch interpretiert?
>Diese Möglichkeit solltest Du in Betracht ziehen.
Code-Gebrabbel ist keine Strategie gegen Irrtuemer und Wissensdefizite.
>>>Darüberhinaus besteht die theoretische, wenn auch
>>>unwahrscheinliche, Möglichkeit, daß int und unsigned in verschiedenen
>>>Registern übergeben werden.
>>
>> 1. gibt's in C keine Parameteruebergabe "in Registern", der Standard
>> schweigt sich da aus;
>Der Standard verlangt, daß %u ein unsigned übergeben wird.
Falsch. Er sagt, dass printf() zu den Spezifizierern `u', `x' und `o'
ein `unsigned int'-Argument erwartet. Siehst Du, was der Unterschied
ist?
> Wie genau,
>und mit welchem Mechanismus ist völlig Wurst.
Richtig. Deswegen taugt ja auch ein spezieller Mechanismus, wenn der
illustrieren soll, dass das eine oder andere Verstaendnis von der
Sprache richtig oder falsch ist, nicht.
> Register stellen eine
>Möglichkeit dar (die ich mir einfach so ausgedacht habe, was mir laut
>Standard frei steht).
Du kannst Dir ausdenken, gar implementieren, was immer Du willst. Hast
Dich allerdings danach der Frage zu stellen, ob Du damit den Anforder-
ungen Sprache gerecht wirst. Du hast aber das Ganze umgedreht, Dir eine
Methode zur Parameteruebergabe ausgedacht und wolltest mit der zeigen,
dass Dein Verstaendnis von der Sprache richtig sei. Tatsaechlich irrst
Du Dich aber hier, und Dein Mechanismus funktioniert nicht.
> > wenn allerdings und 2. ein Implementeur einen
>> Mechanismus bastelt, der dazu fuehrt, dass obiger Code crasht, dann
>> gehoeren ihm Paragraphen um die Ohren gehauen.
>Damit hast Du Recht, aber das heißt nicht, daß Du %u ein int geben darfst.
Du redest wirr und widersprichst Dir selbst. Ich kann nicht Recht haben
und gleichzeitig kein (positives) int uebergeben duerfen.
b.
Gelaber ohne Grundlage. Ablenkungsmanöver.
>>>>Warum willst Du sowas wie
>>>
>>>> int i = 42;
>>>> printf("%u\n", i);
>>>
>>>>unterstützen?
>>>
>>>Erstmal "unterstuetze" nicht ich das, sondern die Sprache; ich's wuerde
>>>es allerdings und tatsaechlich genauso schreiben, weil's Code-Gebrabbel
>>>erspart und ich ueberhaupt nicht einsehe, warum man die Sprache nicht
>>>in und mit all ihren Feinheiten auch be-, meinetwegen auch "aus-"nutzt.
>
>>Falls man sich irrt und den Standard falsch interpretiert?
>>Diese Möglichkeit solltest Du in Betracht ziehen.
>
> Code-Gebrabbel ist keine Strategie gegen Irrtuemer und Wissensdefizite.
Die Möglichkeit in Betracht zu ziehen, Du hättest Wissensdefizite oder
irrst Dich, kommt für Dich nicht in Frage?
>>>>Darüberhinaus besteht die theoretische, wenn auch
>>>>unwahrscheinliche, Möglichkeit, daß int und unsigned in verschiedenen
>>>>Registern übergeben werden.
>>>
>>>1. gibt's in C keine Parameteruebergabe "in Registern", der Standard
>>>schweigt sich da aus;
>
>>Der Standard verlangt, daß %u ein unsigned übergeben wird.
>
> Falsch.
Nein, richtig.
> Er sagt, dass printf() zu den Spezifizierern `u', `x' und `o'
> ein `unsigned int'-Argument erwartet. Siehst Du, was der Unterschied
> ist?
Und er sagt:
9 If a conversion specification is invalid, the behavior is undefined.239) If any
argument is not the correct type for the corresponding conversion specification,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
the behavior is undefined.
>>Wie genau,
>>und mit welchem Mechanismus ist völlig Wurst.
>
> Richtig. Deswegen taugt ja auch ein spezieller Mechanismus, wenn der
> illustrieren soll, dass das eine oder andere Verstaendnis von der
> Sprache richtig oder falsch ist, nicht.
Was? Ein Gegenbeispiel *ist* ein Beweis.
>>Register stellen eine
>>Möglichkeit dar (die ich mir einfach so ausgedacht habe, was mir laut
>>Standard frei steht).
>
> Du kannst Dir ausdenken, gar implementieren, was immer Du willst.
Stimmst Du mir zu, daß der Standard die Möglichkeit erlaubt, verschiedene
Register für Parameter unterschiedlichen Typs zu benutzen?
> Hast
> Dich allerdings danach der Frage zu stellen, ob Du damit den Anforder-
> ungen Sprache gerecht wirst.
Ja.
> Du hast aber das Ganze umgedreht, Dir eine
> Methode zur Parameteruebergabe ausgedacht und wolltest mit der zeigen,
> dass Dein Verstaendnis von der Sprache richtig sei. Tatsaechlich irrst
> Du Dich aber hier, und Dein Mechanismus funktioniert nicht.
Das behauptest Du.
>>>wenn allerdings und 2. ein Implementeur einen
>>>Mechanismus bastelt, der dazu fuehrt, dass obiger Code crasht, dann
>>>gehoeren ihm Paragraphen um die Ohren gehauen.
>
>>Damit hast Du Recht, aber das heißt nicht, daß Du %u ein int geben darfst.
>
> Du redest wirr und widersprichst Dir selbst. Ich kann nicht Recht haben
> und gleichzeitig kein (positives) int uebergeben duerfen.
Wieso? Ich bin auch der Meinung, daß es blöd wäre, Parameterübergabe so zu
implementieren. Davon abgesehen kann ich gar nicht wirr reden, was daran liegt,
daß ich hier überhaupt nicht rede.
Du bist nicht in der Lage zwei einfache und deutliche Passagen aus dem Standard
zu verstehen und suchst stattdessen an anderen irrelevanten Stellen nach Indizien,
die Deine Meinung belegen. Was genau hast Du an 7.19.6.1#9 nicht verstanden?
Jirka
Hör auf abzulenken und nimm endlich dazu Stellung, was Deiner Meinung
nach an 7.19.6.1#9 nicht klar ist.
> In den beiden Zeilen stecken keine
> Annahmen ueber Typ-Groessen; wenn sie trotzdem UB sein sollen, sind's
> so gut wie alle C-Programme.
>
> Du gehst auch mit keinem Wort auf mehrfach angefuehrte Passagen des
> Standards ein, und hast dazu noch etwas Entscheidenes im Code oben
> uebersehen: Dass die 4 auszugebenen Zeichen kleiner gleich SCHAR_MAX
> sind, egal, ob plain char vorzeichenbehaftet ist oder nicht.
Na und? Nachdem sie zu unsigned int "promotet" worden sind, schlägt
Paragraph 9 zu.
Jirka
Wie oft noch? If the ... passed to printf is not of the correct type.
Bestenfalls widerspricht sich dieses Dokument an mehreren Stellen (=>
defect report) und jede weitere Annahme kann man nicht gesichert
machen, falls überhaupt eine notwendig ist: This is meant to imply
interchangeability as arguments to functions, [...]. printf ist eine
function, oder muß sich andernfalls wie eine verhalten, muß also int
für unsigned und umgekehrt akzeptieren.
Ein int mit positivem Wertebereich ist ein korrekter Typ für `u', `x' und `o'
Spezifiziereren, da dieser mit einem unsigned int austauschbar ist.
Dies folgt eindeutig aus
6.2.5
[#9] The range of nonnegative values of a signed integer
type is a subrange of the corresponding unsigned integer
type, and the representation of the same value in each type
is the same.31) A computation involving unsigned operands
...
31)The same representation and alignment requirements are
meant to imply interchangeability as arguments to
functions, return values from functions, and members of
unions.
Grüße
Erich
--
New Version of EFEU released, More fun with Tk support.
Get the open source from http://efeu.cybertec.at now.
Daraus folgt es überhaupt nicht.
> 31)The same representation and alignment requirements are
> meant to imply interchangeability as arguments to
> functions, return values from functions, and members of
> unions.
Fußnoten sind nicht normativ. Absatz 7.19.6.1#9 dagegen ist normativ.
Mag sein, daß die Fußnote die Intention der Schreiber wiedergibt. Im
normativen Teil des Standards wird das jedoch *nicht* so ausgedrückt.
Jirka
Exakt. Sie dienen der Erläuterung, falls man animmt, Teile der
Leserschaft würden den Text sonst kreativer mißverstehen, als er
gemeint war. Kaputtkriegen kann man alles, vgl Steuerrecht.
>>>>>>>char a = -100;
>>>>>>>printf("number: %x \n", (unsigned char) c);
>>>>>>>... muss ich hier noch zusätzlich noch auf unsigned int casten?
>>>OK, dann eben ganz deutlich. Ja, man muß casten.
>>
>> Behauptung wiederholt, belegt mit Fussaufstampfen.
>Gelaber ohne Grundlage. Ablenkungsmanöver.
Ich habe mich wohl verhoert. Ich versuche Dir (nicht mehr lange) auf
allen moeglichen Wegen klarzumachen, dass Du daneben liegst, und werde
so'n verbalen Stuss kaum laenger anhoeren.
>>>Falls man sich irrt und den Standard falsch interpretiert?
>>>Diese Möglichkeit solltest Du in Betracht ziehen.
>>
>> Code-Gebrabbel ist keine Strategie gegen Irrtuemer und Wissensdefizite.
>Die Möglichkeit in Betracht zu ziehen, Du hättest Wissensdefizite oder
>irrst Dich, kommt für Dich nicht in Frage?
Sicher nicht in diesem Thread, oder deutlicher: Fasse Dich an die
eigene Nase.
>>>Der Standard verlangt, daß %u ein unsigned übergeben wird.
>>
>> Falsch.
>Nein, richtig.
Und wieder: Beleg durch Fussaufstampfen.
# The format is composed of zero or more directives: [...] and
# conversion specifications, each of which results in *fetching* zero
# or more subsequent *arguments*, converting them, if applicable, ...
# 7.19.6.1p3
und
# o,u,x,X The unsigned int *argument* is converted to [...]
# 7.19.6.1p8
Bitte siehe nach, was ein "Argument" ist; nicht das, was "uebergeben"
wird (das ist ein "Parameter"), sondern das, was gefunden wird, mithin
*erwartet* printf() ein unsigned int.
> > Er sagt, dass printf() zu den Spezifizierern `u', `x' und `o'
>> ein `unsigned int'-Argument erwartet. Siehst Du, was der Unterschied
>> ist?
>Und er sagt:
>9 If a conversion specification is invalid, the behavior is undefined.239) If any
> argument is not the correct type for the corresponding conversion specification,
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> the behavior is undefined.
1. Siehe einen Absatz hoch und 2. *ist* ein positives int der korrekte
Typ, wenn ein unsigned int erwartet wird.
>>>Wie genau,
>>>und mit welchem Mechanismus ist völlig Wurst.
>>
>> Richtig. Deswegen taugt ja auch ein spezieller Mechanismus, wenn der
>> illustrieren soll, dass das eine oder andere Verstaendnis von der
>> Sprache richtig oder falsch ist, nicht.
>Was? Ein Gegenbeispiel *ist* ein Beweis.
Dein "Gegenbeispiel" war ein Mechanismus, der nicht funktioniert. Was
soll das "beweisen"?
>>>Register stellen eine
>>>Möglichkeit dar (die ich mir einfach so ausgedacht habe, was mir laut
>>>Standard frei steht).
>>
>> Du kannst Dir ausdenken, gar implementieren, was immer Du willst.
>Stimmst Du mir zu, daß der Standard die Möglichkeit erlaubt, verschiedene
>Register für Parameter unterschiedlichen Typs zu benutzen?
Der Standard macht keine Aussagen, wie Parameter uebergeben werden, also
"erlaubt" oder "verbietet" er auch nichts. Aber:
>> Hast
>> Dich allerdings danach der Frage zu stellen, ob Du damit den Anforder-
>> ungen Sprache gerecht wirst.
>Ja.
>> Du hast aber das Ganze umgedreht, Dir eine
>> Methode zur Parameteruebergabe ausgedacht und wolltest mit der zeigen,
>> dass Dein Verstaendnis von der Sprache richtig sei. Tatsaechlich irrst
>> Du Dich aber hier, und Dein Mechanismus funktioniert nicht.
>Das behauptest Du.
Es wird absurd. Du hoerst nicht nicht zu und verschliesst Dich
jeglicher Logik. Hast Du Dir diese int- und unsigned int-Register-
Uebergabe ausgedacht? Hast Du gezeigt, das sie "den Anforderungen
Sprache gerecht" wird? Wolltest Du dennoch mit ihr etwas zeigen? Also.
Dass sie nicht funktioniert, liegt direkt auf der Hand: Vorzeichenlose
int-Parameter koennen mit ihr nicht als unsigned-Argumente gefunden
werden.
>Du bist nicht in der Lage zwei einfache und deutliche Passagen aus dem Standard
>zu verstehen und suchst stattdessen an anderen irrelevanten Stellen nach Indizien,
>die Deine Meinung belegen. Was genau hast Du an 7.19.6.1#9 nicht verstanden?
Nichts und ich "suche" nicht, sondern alles liegt auf dem Tisch. Dein
Problem ist, dass Du penetrant "Argument" und "Parameter" nicht
auseinander haeltst und *vor allem* 6.5.2.2p6 nicht zur Kenntnis nehmen
willst. Nicht zum ersten Mal:
# If the function is defined with a type that does not include a
# prototype, and the types of the arguments after promotion are not
# compatible with those of the parameters after promotion, the behavior
# is undefined, except for the following cases:
# -- one promoted type is a signed integer type, the other
# promoted type is the corresponding unsigned integer
# type, and the value is representable in both types;
Was ist daran nicht zu verstehen?
Zum letzten Mal auf die konkrete printf()-Situation angewendet:
Sind Ellipsen-Argumente mit Prototype deklariert? Nein. Also,
werden dann Argumente und Parameter promotet? Ja.
Erwartet printf() zu "%x" ein unsigned int? Ja.
Ist 42 (bei beliebig erlaubten Typ-Groessen) ein vorzeichenloses int?
Ja.
Wird das noch promotet? Nein.
Also: Passen Parameter und Argument zusammen? Ja, wegen des
Spiegelstrichs.
QED
Die dritt- und vorletzten Fragen und Antworten sehen beim
-urspruenglichen `char c = 100; printf(...,(unsigned char) c);'
natuerlich etwas anders aus, das Result, samt QED ist dennoch das
gleiche.
WAS SIEHST DU ANDERS?
b.
>Erich Fruehstueck wrote:
>> Jirka Klaue <jkl...@ee.tu-berlin.de> wrote:
>...
>>>9 If a conversion specification is invalid, the behavior is undefined.239) If any
>>> argument is not the correct type for the corresponding conversion specification,
>>> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>> the behavior is undefined.
>>
>> Ein int mit positivem Wertebereich ist ein korrekter Typ für `u', `x' und `o'
>> Spezifiziereren, da dieser mit einem unsigned int austauschbar ist.
>> Dies folgt eindeutig aus
>>
>> 6.2.5
>>
>> [#9] The range of nonnegative values of a signed integer
>> type is a subrange of the corresponding unsigned integer
>> type, and the representation of the same value in each type
>> is the same.31) A computation involving unsigned operands
>> ...
>Daraus folgt es überhaupt nicht.
Das allerdings ist schon richtig.
>> 31)The same representation and alignment requirements are
>> meant to imply interchangeability as arguments to
>> functions, return values from functions, and members of
>> unions.
>Fußnoten sind nicht normativ. Absatz 7.19.6.1#9 dagegen ist normativ.
>Mag sein, daß die Fußnote die Intention der Schreiber wiedergibt. Im
>normativen Teil des Standards wird das jedoch *nicht* so ausgedrückt.
Die Fussnote erklaert (oder meinetwegen: macht plausibel) ja auch nur
an der Stelle, warum der Standard diese besonderen Zusicherungen zur
Kodierung von Ganzzahltypen macht. Angewendet auf Funktionsrufe wird
das Ganze 6.5.2.2p6.
Alles nicht zum 1. Mal gesagt und geschrieben.
b.
Also was?
Das Problem ist alt und wurde auch schon des öfteren diskutiert. Es
scheint keine Einigkeit unter den Experten zu herrschen. Lawrence Kirby
vertrat deinen jetzigen Standpunkt. Dan Pop, Tanmoy Bhattacharya und
Kaz Kylheku argumentierten dagegen. Auch das Registerbeispiel wurde schon
oft diskutiert und mit der Beurteilung "absurd" stehst Du wohl allein da.
Lies doch z.B. mal den Thread der auf diesen Artikel folgt:
3319DD...@netrunner.net, es gibt auch noch weitere.
Ich bin es auch leid, mit Dir zu diskutieren. Ich werde weiterhin %u mit
unsigned füttern. Wenn Du an einer Klärung des Sachverhalts durch Experten
interessiert bist, schlage ich comp.std.c vor. Und schrei nicht rum.
Jirka
Jirka Klaue <jkl...@ee.tu-berlin.de> writes:
>Andreas Burmester wrote:
>> Jirka Klaue <jkl...@ee.tu-berlin.de> writes:
>>>>>>Christoph Rabel <od...@hal9000.vc-graz.ac.at> writes:
>>>>>>>char a = -100;
>>>>>>>printf("number: %x \n", (unsigned char) c);
>>>>>>>... muss ich hier noch zusätzlich noch auf unsigned int casten?
>>>OK, dann eben ganz deutlich. Ja, man muß casten.
>>
>> Behauptung wiederholt, belegt mit Fussaufstampfen.
>Gelaber ohne Grundlage. Ablenkungsmanöver.
Ich habe mich wohl verhoert. Ich versuche Dir (nicht mehr lange)
zielgerichtet, aber allen moeglichen Wegen klarzumachen (weil der
direkte - "Standard zitieren" - nicht wirkt), dass Du daneben liegst,
und werde mir solch' verbale Entgleisungen kaum noch einmal zumuten.
>>>Falls man sich irrt und den Standard falsch interpretiert?
>>>Diese Möglichkeit solltest Du in Betracht ziehen.
>>
>> Code-Gebrabbel ist keine Strategie gegen Irrtuemer und Wissensdefizite.
>Die Möglichkeit in Betracht zu ziehen, Du hättest Wissensdefizite oder
>irrst Dich, kommt für Dich nicht in Frage?
Sicher nicht in diesem Thread, oder deutlicher: Fass' Dir an die eigene
Nase.
>>>Der Standard verlangt, daß %u ein unsigned übergeben wird.
>>
>> Falsch.
>Nein, richtig.
# The format is composed of zero or more directives: [...] and
# conversion specifications, each of which results in *fetching* zero
# or more subsequent *arguments*, converting them, if applicable, ...
# 7.19.6.1p3
und
# o,u,x,X The unsigned int *argument* is converted to [...]
# 7.19.6.1p8
Bitte siehe nach, was ein "Argument" ist; nicht das, was "uebergeben"
wird (das ist ein "Parameter"), sondern das, was gefunden wird, mithin
*erwartet* printf() ein unsigned int.
> > Er sagt, dass printf() zu den Spezifizierern `u', `x' und `o'
>> ein `unsigned int'-Argument erwartet. Siehst Du, was der Unterschied
>> ist?
>Und er sagt:
>9 If a conversion specification is invalid, the behavior is undefined.239) If any
> argument is not the correct type for the corresponding conversion specification,
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> the behavior is undefined.
1. Siehe einen Absatz hoch, und 2. *hat* ein positiver int-Wert den
korrekten Typ, wenn ein unsigned int erwartet wird.
>>>Wie genau,
>>>und mit welchem Mechanismus ist völlig Wurst.
>>
>> Richtig. Deswegen taugt ja auch ein spezieller Mechanismus, wenn der
>> illustrieren soll, dass das eine oder andere Verstaendnis von der
>> Sprache richtig oder falsch ist, nicht.
>Was? Ein Gegenbeispiel *ist* ein Beweis.
Dein "Gegenbeispiel" war ein Mechanismus, der nicht funktioniert. Was
soll es also "beweisen"?
>>>Register stellen eine
>>>Möglichkeit dar (die ich mir einfach so ausgedacht habe, was mir laut
>>>Standard frei steht).
>>
>> Du kannst Dir ausdenken, gar implementieren, was immer Du willst.
>Stimmst Du mir zu, daß der Standard die Möglichkeit erlaubt, verschiedene
>Register für Parameter unterschiedlichen Typs zu benutzen?
Der Standard macht keine Aussagen, wie Parameter uebergeben werden, also
"erlaubt" oder "verbietet" er auch nichts. Aber:
>> Hast
>> Dich allerdings danach der Frage zu stellen, ob Du damit den Anforder-
>> ungen Sprache gerecht wirst.
>Ja.
>> Du hast aber das Ganze umgedreht, Dir eine
>> Methode zur Parameteruebergabe ausgedacht und wolltest mit der zeigen,
>> dass Dein Verstaendnis von der Sprache richtig sei. Tatsaechlich irrst
>> Du Dich aber hier, und Dein Mechanismus funktioniert nicht.
>Das behauptest Du.
Es wird absurd. Du hoerst nicht nicht zu und verschliesst Dich
jeglicher Logik. Hast Du Dir diese int- und unsigned int-Register-
Uebergabe ausgedacht? Hast Du gezeigt, dass sie "den Anforderungen
Sprache gerecht" wird? Wolltest Du dennoch mit ihr etwas zeigen? Also.
Dass sie nicht funktioniert, liegt direkt auf der Hand: Positive
int-Parameter koennen mit ihr nicht als unsigned int-Argumente gefunden
werden.
>Du bist nicht in der Lage zwei einfache und deutliche Passagen aus dem Standard
>zu verstehen und suchst stattdessen an anderen irrelevanten Stellen nach Indizien,
>die Deine Meinung belegen. Was genau hast Du an 7.19.6.1#9 nicht verstanden?
Nichts und ich "suche" auch nichts, sondern alles liegt auf dem Tisch.
Dein Problem ist, dass Du penetrant "Argument" und "Parameter" nicht
auseinander haeltst und *vor allem*, aber genauso penetrant 6.5.2.2p6
nicht zur Kenntnis nehmen willst. Nicht zum ersten Mal:
# If the function is defined with a type that does not include a
# prototype, and the types of the arguments after promotion are not
# compatible with those of the parameters after promotion, the behavior
# is undefined, except for the following cases:
# -- one promoted type is a signed integer type, the other
# promoted type is the corresponding unsigned integer
# type, and the value is representable in both types;
Was ist daran nicht zu verstehen?
Zum letzten Mal auf die konkrete printf()-Situation angewendet:
Sind Ellipsen-Argumente mit Prototype deklariert? Nein. Also,
werden dann Argumente und Parameter promotet? Ja.
Erwartet printf() zu "%x" ein unsigned int? Ja.
Ist 42 (bei beliebig erlaubten Typ-Groessen) ein positives int? Ja.
Wird die noch promotet? Nein.
Also: Passen Parameter und Argument (im Sinn von "correct type for the
corresponding conversion specification") zusammen? Ja, wegen der Zu-
sicherung im Spiegelstrich.
QED
Die dritt- und vorletzten Fragen und Antworten sehen beim ursprueng-
lichen `char c = -100; printf(...,(unsigned char) c);' natuerlich etwas
anders aus, das Resultat, samt QED ist dennoch das selbe.
WAS SIEHST DU DA ANDERS?
b.
Das ist eine ganz einfache Sache: Du implementierst das, verkaufst es
erfolgreich meinem momentanen Arbeitgeber und danach sorge ich dafür,
daß Du dem nie wieder irgendetwas verkaufst, einschließlich Dir
selber.
[ %u ]
> Das hatte ich doch schon vor langer Zeit anhand mehrerer Stellen
> aus dem Standard bewiesen - per langem Thread.
>
> Es hat mir eben nicht jeder geglaubt, weil, wenn ich Standard-Zeilen zeige,
> sind sie 'von Schellong berührt' und folglich ausnahmsweise
> irrelevant.
Das hat Heinlein in 'lifeline' mal sehr schön auf den Punkt gebracht
(Paraphrase): Akademiker lieben Theorien, denn über die kann man
Bücher schreiben, ohne sich mit Messungen abgeben zu müssen. Die läßt
man von Hiwis durchführen und falls die Ergebnisse nicht zur Theorie
passen, werden sie passend gerechnet, Danach gehen sie verloren und
werden aus den zurechtgerechneten Werten zurückgerechnet. Der Hiwi
wird danach entlassen und man sucht sich jemand willfährigeren.
'Business as usual. Move on, folks'
Es will mir jedenfalls nicht einleuchten, daß
printf("%u", 123);
schieflaufen könnte...
> Wenn Du an einer Klärung des Sachverhalts durch Experten
> interessiert bist, schlage ich comp.std.c vor.
Ich habe da mal nachgefragt.
--
Falk
>> Es wird absurd. Du hoerst nicht nicht zu und verschliesst Dich
>> jeglicher Logik. Hast Du Dir diese int- und unsigned int-Register-
>> Uebergabe ausgedacht? Hast Du gezeigt, das sie "den Anforderungen
>> Sprache gerecht" wird? Wolltest Du dennoch mit ihr etwas zeigen? Also.
>Also was?
"Also" ist eine Antwort, wie "Das behauptest Du.", zur Demontage Deiner
Argumentationskette absurd. Die Fragen waren Vorhalte, die's belegen.
>Das Problem ist alt und wurde auch schon des öfteren diskutiert. Es
>scheint keine Einigkeit unter den Experten zu herrschen. Lawrence Kirby
>vertrat deinen jetzigen Standpunkt. Dan Pop, Tanmoy Bhattacharya und
>Kaz Kylheku argumentierten dagegen. Auch das Registerbeispiel wurde schon
>oft diskutiert und mit der Beurteilung "absurd" stehst Du wohl allein da.
>Lies doch z.B. mal den Thread der auf diesen Artikel folgt:
>3319DD...@netrunner.net, es gibt auch noch weitere.
Du spielst mit gezinkten Karten, und "alt" ist wahr - der angegebene
Thread ueber 6 Jahre (!), also weit vor C99, und in C89 findet sich
weder diese notorische Fussnote 31, vor allem aber nicht die beiden
mehrfach angefuehrten Passagen, dass promovierte Parameter und
Argumenten zueinander passen, wenn "one promoted type is a signed
integer type, the other promoted type is the corresponding unsigned
integer type, and the value is representable in both types". Die machen
den Unterschied zu frueher.
Das erklaert IMO auch, warum zu Beginn des Threads Einige, jetzt nur
Du's fuer UB haeltst. Ich war frueher gleicher Meinung.
>Ich bin es auch leid, mit Dir zu diskutieren.
Dazu war es ja nicht gekommen, weil Du o.a. Passagen nicht zur
Kenntnis, wenigstens aber keine Stellung nehmen wolltest und willst.
> Ich werde weiterhin %u mit
>unsigned füttern.
Das bleibt Dir unbenommen, mag sogar vernuenftig sein (wenn die Werte,
die uebergeben werden, nicht so offensichtlich sind); hat aber mit der
Frage, ob man in diesem Fall casten *muesse*, nichts zu tun.
Wenn Du's allerdings mit der Begruendung eines sonst vermeintlich
vorhandenen UBs machst, denke bitte in Zukunft 'dran, auch jedes char
zu casten, wenn's mit %c ausgegeben werden soll.
> Wenn Du an einer Klärung des Sachverhalts durch Experten
>interessiert bist, schlage ich comp.std.c vor.
Erstmal: Lesen und verstehen koennen wir ja wohl selbst, und falls es
zu einem Dissenz kommt, kann und muss man argumentieren, wer was
missverstanden hat. Das setzt allerdings voraus, dass man sich a) mit
der Gegenposition auseinander setzt und b) ggf. Irrtuemer eingesteht.
Ich kann mir jetzt auch nicht verkneifen, an wechselseitige
Union-Zugriffe zu erinnern, die jemand fuer "eine gute Idee" hielt...
Mir ist zwar nicht klar, warum das noetig gewesen sein sollte, aber zum
Anderen hat das Falk Hueffner offensichtlich gemacht. Meinung dort war,
dass nach (wenigstens) der Intention der Standardautoren dieses
`printf("%u",42);' kein UB ist, sie's allerdings praeziser haetten
formulieren sollen - was wohl passieren wird.
> Und schrei nicht rum.
Ich gebe zu, dass ich manchmal recht unwirsch werde, wenn ich merke,
dass in einem Fachdisput auf sachliche Argumente nicht eingegangen
wird. So wie jetzt wieder. Denn was hat ein Insistieren auf
Beantwortung von Fragen mit Deiner Replik zu tun? Du hast Dich wieder
'dran vorbei gemogelt.
b.
Es gibt (wie ich schon schrieb) mehr davon, auch neueren Datums.
> weder diese notorische Fussnote 31, vor allem aber nicht die beiden
> mehrfach angefuehrten Passagen, dass promovierte Parameter und
> Argumenten zueinander passen, wenn "one promoted type is a signed
> integer type, the other promoted type is the corresponding unsigned
> integer type, and the value is representable in both types". Die machen
> den Unterschied zu frueher.
>
> Das erklaert IMO auch, warum zu Beginn des Threads Einige, jetzt nur
^^^
> Du's fuer UB haeltst.
Woher willst Du das wissen?
>>Wenn Du an einer Klärung des Sachverhalts durch Experten
>>interessiert bist, schlage ich comp.std.c vor.
>
> Erstmal: Lesen und verstehen koennen wir ja wohl selbst, und falls es
Mag ja sein, aber comp.std.c ist genau für die Klärung solcher Fragen
da, meinst Du nicht?
> zu einem Dissenz kommt, kann und muss man argumentieren, wer was
> missverstanden hat. Das setzt allerdings voraus, dass man sich a) mit
> der Gegenposition auseinander setzt und b) ggf. Irrtuemer eingesteht.
Wenn ich die Argumente in csc richtig verstanden habe, dann läuft es
auf folgendes hinaus:
- D. Gwyn sagt, daß es nicht in der Absicht der Schreiber lag,
printf("%u", 123) undefined zu lassen.
- Er kann es aber nicht mit dem normativen Text des Standards zeigen.
- J. Kuyper sagt zu der ominösen Fußnote:
"People have misread it as actually promising interchangeability,
which it does not."
- Insbesondere hat niemand D. Pop widersprochen, der sagt, daß
7.19.6.1#9 alle anderen (allgemeineren) Passagen aufhebt.
- L. Jones sagt:
> Which interpretation is correct?
"Yes. Or no. Take your pick. If you want to know for sure, have your
national body (or another sympathetic national body) submit a DR to the
committee."
Letzlich gibt es wenig Aussagen für die Legalität von printf("%u", 123),
jedoch einige dagegen. Eine endgültige Antwort kann *nur* ein Defect Report
erbringen.
> Ich kann mir jetzt auch nicht verkneifen, an wechselseitige
> Union-Zugriffe zu erinnern, die jemand fuer "eine gute Idee" hielt...
Inzwischen weiß ich, daß das keine gute Idee ist.
Aber was hat das mit printf zu tun?
> Mir ist zwar nicht klar, warum das noetig gewesen sein sollte,
Es ist wohl nötig, da wir uns bei der Argumentation im Kreise drehen und
ein Großteil der Diskussion nicht mehr mit fachlichen Argumenten geführt
wurde, was vielleicht den Unterhaltungswert erhöht aber letzlich nicht
zur Klärung führen kann.
Jirka
Jaja, printf("%u\n", 123) schreibt man ja sowieso nicht. // puts("123");
> hat aber mit der Frage, ob man in diesem Fall casten *muesse*, nichts zu tun.
Ich werde auch weiterhin empfehlen, %u nur unsigned zu übergeben.
> Wenn Du's allerdings mit der Begruendung eines sonst vermeintlich
> vorhandenen UBs machst, denke bitte in Zukunft 'dran, auch jedes char
> zu casten, wenn's mit %c ausgegeben werden soll.
Das muß man wohl wirklich tun, wenn man strikte Konformität erzielen möchte.
Jirka
>>>Lies doch z.B. mal den Thread der auf diesen Artikel folgt:
>>>3319DD...@netrunner.net, es gibt auch noch weitere.
>>
>> Du spielst mit gezinkten Karten, und "alt" ist wahr - der angegebene
>> Thread ueber 6 Jahre (!), also weit vor C99, und in C89 findet sich
>Es gibt (wie ich schon schrieb) mehr davon, auch neueren Datums.
Und die beruecksichtigen die beiden x-mal angefuehrten Passagen aus
C99? Dann waere ich ja nicht gerade mit so'ner Klamotte gekommen...
>> Das erklaert IMO auch, warum zu Beginn des Threads Einige, jetzt nur
> ^^^
>> Du's fuer UB haeltst.
>Woher willst Du das wissen?
Niemand, ausser Dir insistiert noch auf den Cast. Wenigstens hier.
Uebrigens hast Du einen Knick in Deiner '^'-Zieloptik. :)
>Wenn ich die Argumente in csc richtig verstanden habe, dann läuft es
>auf folgendes hinaus:
> - D. Gwyn sagt, daß es nicht in der Absicht der Schreiber lag,
> printf("%u", 123) undefined zu lassen.
> - Er kann es aber nicht mit dem normativen Text des Standards zeigen.
> - J. Kuyper sagt zu der ominösen Fußnote:
> "People have misread it as actually promising interchangeability,
> which it does not."
> - Insbesondere hat niemand D. Pop widersprochen, der sagt, daß
> 7.19.6.1#9 alle anderen (allgemeineren) Passagen aufhebt.
> - L. Jones sagt:
> > Which interpretation is correct?
> "Yes. Or no. Take your pick. If you want to know for sure, have your
> national body (or another sympathetic national body) submit a DR to the
> committee."
Dann hast Du eher den Thread recht selektiv wahrgenommen, denn:
- Streiche erstmal alles rund um die Fussnote - dass die nicht normativ
ist, war nicht strittig. Sie drueckt nur, allerdings explizit, die
Intention der Standardautoren aus.
- An Dan Pops Betonung von 7.19.6.1p6 ist nichts auszusetzen, er
flechte aber dovor die Kette:
- printf() sei keine "User"-Funktion, und deswegen sei nicht gesagt,
dass
- sie in C geschrieben sein, und
- sie die aktuellen Ellipsen-Argumente mit stdarg-Methoden hole,
daher finde auch
- 7.15.1.1p2 (wo die bekannte Zusicherung wortgleich ein 2. Mal
steht) keine Anwendung und
- es gelte "nur" 7.19.6.1p6.
Damit wir uns richtig verstehen: Ich halte seine Argumentationsweise
grundsaetzlich fuer richtig und zulaessig. Nur ist sie in diesem Fall
an den Haaren herbei gezogen, spitzfindig und jenseits jeglicher
Realitaet. Weil die Standardautoren offensichtlich nichts davon
gemeint haben, sie haben lediglich versaeumt, es mit einem Satz
auszuschliessen, wie "Standardfunktionen verhalten sich so, als
waeren ..." o.ae.
- Was Du dagegen nicht wahrgenommen hast, ist dass er sich 'drum herum
gedrueckt, zu sagen, ob denn dann Ellipsen-Argumente in
Standardfunktionen ueberhaupt promotet werden. Die Zusicherung ist
naemlich in "nur" 7.19.6.1p6 nicht zu finden. Waeren er und Du
konsequent, muesstet ihr nicht nur in "%u" und 42 casten, sondern
auch bei jedem char (*), short, jeweils auch unsigned, und floats.
U.a. daran laesst sich sehen, dass seine und Deine vorgetragene
Meinung nichts mit C-Programmen, wie wir sie kennen, zu tun haben.
Sondern mit Mankos, meinetwegen "Defekten" im Standard.
(*) Da habe ich Dich ja schon mit anderer Logik hingetrieben; Falk
Hueffner hat mein Exempel in dcsc ebenfalls vorgetragen, auch
daran hat sich Dan Pop vorbei gedrueckt.
>Letzlich gibt es wenig Aussagen für die Legalität von printf("%u", 123),
>jedoch einige dagegen. Eine endgültige Antwort kann *nur* ein Defect Report
>erbringen.
Na gut, der ist wohl faellig, aber Vernunft und Logik sagen schon
jetzt, was richtig ist.
>> Ich kann mir jetzt auch nicht verkneifen, an wechselseitige
>> Union-Zugriffe zu erinnern, die jemand fuer "eine gute Idee" hielt...
>Inzwischen weiß ich, daß das keine gute Idee ist.
>Aber was hat das mit printf zu tun?
Nichts, aber mit "eingestandenen Irrtuemern". Stand auch so direkt da.
Musst Du eigentlich fast jeden Satz, den Du zitierst erst aus dem
Kontext reissen und dann den Sinn verdrehen?
>> Mir ist zwar nicht klar, warum das noetig gewesen sein sollte,
>Es ist wohl nötig, da wir uns bei der Argumentation im Kreise drehen und
>ein Großteil der Diskussion nicht mehr mit fachlichen Argumenten geführt
>wurde, was vielleicht den Unterhaltungswert erhöht aber letzlich nicht
>zur Klärung führen kann.
Ersteres sehe ich nicht so (wenn Du Dich nicht fallweise Sachargumenten
entziehen wuerdest), letzteres waere doch auch ok, oder? Jedenfalls
sind wir OnTopic, im Gegensatz zu manch anderen, auch namenslosen
Postern.
b.