Das versteh ich nicht ganz... ich dachte mit der expliziten Zuweisung an die char-Variable wäre das erledigt und mein Wert steht in einer 1 Byte Variable? Wieso wird dann printf() ein 4 Byte int übergeben?mfro hat geschrieben:c ist (auf Maschinen, auf denen der Typ char signed ist, das ist nicht immer so) 0xff, also -1, richtig.
Printf() ist eine variadische Funktion. Bei variadischen Funktionen findet für die "..."-Parameter immer eine Typpromotion, in diesem Fall also "int promotion" statt - im printf()-Rumpf landet also ein int mit dem Wert -1 (0xffffffff).Code: Alles auswählen
int printf(const char *format, ...);
Sizeof 'A' (war Cidiosyncracies)
Re: Cidiosyncracies
Re: Cidiosyncracies
Das Stichwort heißt "variadic function" - also eine Funktion, die eine "Ellipsis" (...) als Parameter hat (an den beliebig viele oder auch kein Wert übergeben werden kann).dani93 hat geschrieben: Das versteh ich nicht ganz... ich dachte mit der expliziten Zuweisung an die char-Variable wäre das erledigt und mein Wert steht in einer 1 Byte Variable? Wieso wird dann printf() ein 4 Byte int übergeben?
Im Standard ist definiert, daß bei variadische Funktionen für die "Ellipsis"-Parameter Variablen-Promotion stattfinden soll, d.h. aus char werden ints, aus unsigned chars unsigned ints und aus floats werden doubles. Das macht den Compilerbauern die Implementierung von variadischen Funktionen wesentlich einfacher.
Übrigens: kein Compiler den ich kenne - mit Ausnahme eines uralten Z80 CP/M 8-Bit Compilers, für den das Nachfolgende (aber sonst auch nix mehr

Das würde dazu führen, daß ein evt. nachfolgender, längerer Parameter (ein int, z.B.) auf einer ungeraden Adresse landen würde.
Viele Prozessorarchitekturen quittieren einen Word-Zugriff auf eine ungerade (Stack-) Adresse mit einem Adreßfehler, alle anderen, die damit zurechtkämen, mit erheblichen Performance-Einschränkungen (der Prozessor macht dann aus einem int-Zugriff vier aufeinanderfolgende Byte-Zugriffe). Compilerbauer müssen das demnach auf jeden Fall vermeiden.
Auf den Stack gepackt wird also in jedem Fall mindestens ein short, meist aber ein int (viele Architekturen sind nur mit 8 oder gar 16 Byte Stack-Alignment schnell). Die "oberen" Bits werden von der aufgerufenen Funktion einfach ignoriert.
"Stack Sparen" kann man also nicht, wenn man Funktionen mit char-Parametern definiert.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: Cidiosyncracies
0xff 0xff... ein unsigned char lässt sich ja 1:1 in ein int transformieren.mfro hat geschrieben: Dann kann jetzt sicher jemand die Preisfrage beantworten: wie lautet die Ausgabe: "0xffffffff 0xff" oder "0xff 0xff"?Code: Alles auswählen
const unsigned char c = 0xff; printf("%02x %02x\n", c, (char) c);
Ich gehe davon aus, dass Du hier eine kleine Sammlung hast? Ich schiele vorsichtig auf's Wiki. ^^
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Re: Cidiosyncracies
Leider falschXin hat geschrieben:0xff 0xff... ein unsigned char lässt sich ja 1:1 in ein int transformieren.mfro hat geschrieben: Dann kann jetzt sicher jemand die Preisfrage beantworten: wie lautet die Ausgabe: "0xffffffff 0xff" oder "0xff 0xff"?Code: Alles auswählen
const unsigned char c = 0xff; printf("%02x %02x\n", c, (char) c);

c ist ein unsigned char. 0xff = 255, macht bei der "unsigned int"-Promotion Richtung "variadic function" immer noch 255.
Der Cast nach char (auf den meisten Maschine vorzeichenbehaftet/signed) macht aus "(unsigned char) 0xff" (der zweiten Ausgabe) "(signed char) 0xff" = -1, darauf folgt die "int promotion" -> (int) -1.
Ausgegeben wird also "0xff 0xffffffff"

Wenn Du glaubst, ich würde Liste führen, mit welchen "C-quirks" ich schon alles auf die Fresse geflogen bin, muß ich dich leider enttäuschenXin hat geschrieben:Ich gehe davon aus, dass Du hier eine kleine Sammlung hast? Ich schiele vorsichtig auf's Wiki. ^^

Vieles fällt mir wieder ein, wenn ich mich durchs Forum lese und manches hat sich so eingebrannt, daß es mir immer präsent ist...
Ich fürchte, als "Wiki-Betreuer" bin ich ungeeignet, aber falls jemand meine Ergüsse in Reinform bringen und übertragen will, ist er herzlich eingeladen. Ansonsten würde ich - falls gewünscht - hier halt immer mal wieder einen Beitrag anhängen, wenn mir was ein- oder auffällt (oder wenn ich mal wieder so richtig auf die Schnauze geflogen bin

It's as simple as that. And remember, Beethoven wrote his first symphony in C.
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: Cidiosyncracies
*narf* Nicht mein Tag heute... ^^mfro hat geschrieben:Leider falschXin hat geschrieben:0xff 0xff... ein unsigned char lässt sich ja 1:1 in ein int transformieren.mfro hat geschrieben: Dann kann jetzt sicher jemand die Preisfrage beantworten: wie lautet die Ausgabe: "0xffffffff 0xff" oder "0xff 0xff"?Code: Alles auswählen
const unsigned char c = 0xff; printf("%02x %02x\n", c, (char) c);
.
c ist ein unsigned char. 0xff = 255, macht bei der "unsigned int"-Promotion Richtung "variadic function" immer noch 255.
Der Cast nach char (auf den meisten Maschine vorzeichenbehaftet/signed) macht aus "(unsigned char) 0xff" (der zweiten Ausgabe) "(signed char) 0xff" = -1, darauf folgt die "int promotion" -> (int) -1.
Ausgegeben wird also "0xff 0xffffffff"
Ist gewünscht.mfro hat geschrieben:Ansonsten würde ich - falls gewünscht - hier halt immer mal wieder einen Beitrag anhängen, wenn mir was ein- oder auffällt (oder wenn ich mal wieder so richtig auf die Schnauze geflogen bin).

Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Re: Sizeof 'A' (war Cidiosyncracies)
Na dann
.
Hier ist noch ein Netter aus der gleichen Abteilung:
Was kommt denn hier wohl raus?

Hier ist noch ein Netter aus der gleichen Abteilung:
Code: Alles auswählen
#include <stdio.h>
int main(int argc, char *argv[])
{
const char c = 0xff;
const unsigned char d = 0xff;
printf(" %d\n", c >> 9);
printf(" %d\n", d >> 9);
return 0;
}
It's as simple as that. And remember, Beethoven wrote his first symphony in C.
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: Sizeof 'A' (war Cidiosyncracies)
-1 und 0 erwarte ich. (was wie man sieht ja nichts zu bedeuten hat
)

Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Re: Sizeof 'A' (war Cidiosyncracies)
... und das ist völlig richtig!Xin hat geschrieben:-1 und 0 erwarte ich. (was wie man sieht ja nichts zu bedeuten hat)
Joker-Frage: warum gibt auch der standardkonformste und penibelste Compiler trotz "-Wall" keine Warnung aus, obwohl man eine char Variable (die ja nur 8 Bits hat) um 9 Bits shiftet?
It's as simple as that. And remember, Beethoven wrote his first symphony in C.
- Xin
- nur zu Besuch hier
- Beiträge: 8862
- Registriert: Fr Jul 04, 2008 11:10 pm
- Wohnort: /home/xin
- Kontaktdaten:
Re: Sizeof 'A' (war Cidiosyncracies)
Keine Ahnung, aber nur weil das Ergebnis sich nicht mehr ändert, wird die Aufgabe doch nicht falsch!? Ein Compiler meckert - denke ich - auch nicht, wenn man c *= 1 oder c += 0 schreibt.mfro hat geschrieben:Joker-Frage: warum gibt auch der standardkonformste und penibelste Compiler trotz "-Wall" keine Warnung aus, obwohl man eine char Variable (die ja nur 8 Bits hat) um 9 Bits shiftet?
Lass Dir mit der Antwort mehr Zeit - damit auch andere eine Schätzung abgeben können.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.
Re: Sizeof 'A' (war Cidiosyncracies)
Tip: ein Shift, der über die Breite des Datentyps des Operanden hinausgeht, ist "undefined behaviour" und _muß_ lt. Standard eine Warnung erzeugen.Xin hat geschrieben:Keine Ahnung, aber nur weil das Ergebnis sich nicht mehr ändert, wird die Aufgabe doch nicht falsch!? Ein Compiler meckert - denke ich - auch nicht, wenn man c *= 1 oder c += 0 schreibt.mfro hat geschrieben:Joker-Frage: warum gibt auch der standardkonformste und penibelste Compiler trotz "-Wall" keine Warnung aus, obwohl man eine char Variable (die ja nur 8 Bits hat) um 9 Bits shiftet?
Lass Dir mit der Antwort mehr Zeit - damit auch andere eine Schätzung abgeben können.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.