Ausgangssituation:
Aufgabenstellung für Auszubildenden ist Berechnung eines
Spannungsteilers mit C.
System: Slackware-Linux 32-Bit
Compiler: GCC 5.3.0
Ausgabe: Console.
Er wollte über Bitmuster in einem Array entscheiden, welche Variable
eingelesen werden müssen.
Mit folgendem kam er zu mir (und ich hatte mich gefreut dass da
Engagement vorhanden ist, die letzte printf-Zeile war für ihn zum
Fehlersuchen):
Die Ausgabe der printf-Zeile (bei einer Eingabe 1) ist:
1
Eingabe: 1
2
3
wahl: 1 ; rflags[wahl]: 0x00 ; rflags[0]: 0x0b
Er (und ich auch) hätte für rflags[wahl] den Wert 0x0b erwartet!
Ändert man das Array rflags nach:
1
uint8_trflags[4]={0x0b,0x19,0x1a};
dann ist die Ausgabe wie erwartet:
1
Eingabe: 1
2
3
wahl: 1 ; rflags[wahl]: 0x0b ; rflags[0]: 0x0b
!!!!!
Kann das daran liegen, dass diese 3 unsigned Bytes nicht einmal einem
ganzen Integer (32-Bit = 4 Byte) entspricht und die Adressierung
irgendwo "klemmt" oder ist das ein reguläres Verhalten und ich übersehe
etwas.
Wie gesagt, das Problem ist ja gelöst, aber ich wüsste gerne woran das
liegt.
Wird nach der gleichen Methode eine Auswahl der einzulesenden Variable
vorgenommen und es existieren bspw. 9 Bytes, dann zeigt ein
uint8_t rflags[9]
nicht das "fehlerhafte" Verhalten von
uint8_t rflags[3]
-----------------------------------------------
Irgendwie mag ich nicht glauben, dass ich einem Fehler von GCC auf die
Spur gekommen bin und werde mal sehen, wie sich das zum einen auf einem
64-Bit System und zum anderen mit einer neueren Compilerversion verhält.
Vielleicht aber hat jemand von Euch eine Erklärung für mich !
Ein schönes Wochenende,
JJ
leo schrieb:> Ralph S. schrieb:>> scanf("%d", &wahl);>> ASCII '0' .. '9' ist nicht gleich Zahl 0 .. 9.>> leo
Das ist Humbug, %d liest eine Zahl und keinen ASCII ein (allerdings -
und logischerweise - wie wir am Beitrag von foobar sehen, einen 4-Byte
Wert, der fälschlicherweise einem unsigned char zugeordnet wurde).
foobar schrieb:> Hier hapert es: uint8_t wahl, ...;> ...> scanf("%d", &wahl);>> Der scanf erwartet einen int-Pointer und schreibt auch ein int (4> Bytes).
Das hier ist die richtige Antwort (und mir auf den Kopf haue)
Joachim D. schrieb:> fängt der Index nixht bei 0 an ?
schon, deswegen steht dort ja auch:
1
dat=rflags[wahl-1];
denn: 1 - 1 = 0
--------------------------------------------------
Vielen Dank an foobar
Was foobar schreibt.
Da sollte der Compiler aber eine Warnung raus hauen.
Er muss so eingestellt werden, dass er das macht.
In stdint.h sind auch die Formatspecifier der Typen für scanf mit
definiert.
Yalu X. schrieb:> Das tut er mit -Wall oder -Wformat auch, sogar sehr ausführlich:
Das war der Hinweis, die Warnungen zu aktivieren und dann auch zu
beachten.
"Sind ja nur Warnungen. Egal, die EXE hat er ja gemacht."
Smile, die Warnungen hat er auch ausgegeben... allerdings (Asche auf
mein Haupt) waren die Warnungen weit oberhalb der nachfolgenden
Compilermeldungen anderer eingebundener Sourcen und nicht zu sehen und
ich habs bei der Durchsicht auf dem Ausbildungsrechner nicht bemerkt.
Im übrigen gebe ich der Einfachkeit wegen die Programmierübungen auf
einem Linuxsystem aus und vin daher wird keine .exe erzeugt.
Aaaber, foobar hats gefunden (und der Compiler auch)... und wer lesen
kann ist klar im Vorteil
Ralph S. schrieb:> daher wird keine .exe erzeugt.
Das EXE ist als Kurzform für Executable gemeint.
DOS (und auch Windows) benötigen das .exe als Dateinamenerweiterung.
*ix Systeme benötigen diese Kennzeichnung nicht. Dennoch bleibt es eine
EXE ?
Wird am Ende keine Erfolgsmeldung (1 Warnung, 0 Fehler) mehr ausgegeben?
Dirk B. schrieb:> *ix Systeme benötigen diese Kennzeichnung nicht. Dennoch bleibt es eine> EXE ?
das stand aber im Kontext zu "... die 'EXE' hat er(der gcc) ja
gemacht..." -
und das ist zumindest missverständlich, denn executables entstehen durch
das das setzen des X-Bits ... und sind keine Aufgaben des `Compilers
oder Linkers
Walter K. schrieb:> und das ist zumindest missverständlich, denn executables entstehen durch> das das setzen des X-Bits ...
Das gibt nur das Recht zur Ausführung.
Kann ich einem Bild (jpg) auch geben, bringt aber nichts.
> ... und sind keine Aufgaben des `Compilers> oder Linkers
Die machen die technische Seite (für Binaries)
Ralph S. schrieb:> Ich kenne kein anderes Forum als das hier (egal welches Fachgebiet), wo> es so extrem pingelig ist wie hier
Aber du hast das doch selbst durch eigene Pingeligkeit angestoßen:
Dirk B. schrieb:> "Sind ja nur Warnungen. Egal, die EXE hat er ja gemacht."Ralph S. schrieb:> Im übrigen gebe ich der Einfachkeit wegen die Programmierübungen auf> einem Linuxsystem aus und vin daher wird keine .exe erzeugt.
Ob das jetzt eine .exe-Datei ist oder nicht, spielt doch gar keine
Rolle. Es ging lediglich darum, dass man Warnungen nicht ignorieren
sollte.
Rolf M. schrieb:> Ob das jetzt eine .exe-Datei ist oder nicht, spielt doch gar keine> Rolle. Es ging lediglich darum, dass man Warnungen nicht ignorieren> sollte.
Warnungen sollte man nie ignorieren, deswegen ja auch "Asche über mein
Haupt". Zudem war das ja "nur" ein Code bei dem ich den Fehler gesucht
habe und der nicht von mir war (der mir aber hätte auch passieren
können).
Schlicht weil in Verbindung mit 8-Bit Controllern eine Variable
(zumindest bei mir) häufiger uint8_t ist.
Wobei: Selbst auf einem 8-Bit System (jetzt aus dem hohlen Bauch heraus)
würde ein
scanf("%d", &wahl);
einen Zeiger auf einen 16-Bit Integer zurück liefern.
Schmunzeln muss: Mit "pingelig" meinte ich, was für eine
Threadverlängerung hier eintritt nachdem die Erklärung bereits geliefert
worden ist.
Ich arbeite mit einem eigenen Konsoleneditor und bin jetzt am überlegen,
wie ich eventuell einen Browser für Compilerwarnungen realisieren
könnte.
Im Moment sieht es so aus, dass es am unteren Bildschirmrand einen
Ausgabe der Compilermeldungen gibt und, wenn dieses zu klein eingestellt
ist man nicht sieht, dass es Warnungen gegeben hat. Ich hätte schlicht
dieses Fenster scrollen sollen und dann wäre mir das wahrscheinlich
(sagen wir zu 90%) aufgefallen.
Allerdings muß ich auch sagen, dass ich beeindruckt bin, wie schnell
manche (hier war es foobar) Programmcodes analysieren und das Falsche
sehen (und ich dachte schon, ich wäre darin gut).
Dass eine Variable den falschen Typ hat habe ich in diesem Fall schlicht
übersehen (und schlichtweg deshalb, weil ich ansonsten mit eigenen
Eingaberoutinen und nicht mit scanf arbeite).
Ralph S. schrieb:> Ich arbeite mit einem eigenen Konsoleneditor und bin jetzt am überlegen,> wie ich eventuell einen Browser für Compilerwarnungen realisieren> könnte.
Selbsterfundene Räder rollen einfach besser…