Hallo Ich habe ein paar kurze Fragen zu C: - Darf ich Signed-Variabeln als Array-Index verwenden? Wo gibt es hier gefahren (ausser, dass sie negativ werden könnten). - Was passiert, wenn ich signed mit unsigned verrechne? - Was passiert, wenn ich eine signed in eine unsigned caste? Gruss Michael
ad 1 Klar darfst du. Gefahren. Hmm. Es gibt da ein auf den ersten Blick merk- würdiges Verbot. Du darfst, wenn du ein Array der Länge n hast, die Adresse des Arrayelementes A[n] bilden. Du darfst nicht auf das Element zugreifen, da es nicht existiert, aber du darfst die Adresse davon bilden. Das gilts aber nicht in die andere Richtung. Du darfst nicht versuchen die Adresse des Arrayelementes A[-1] bilden. Schon alleine der Versuch diese Adresse zu bilden, ist illegal. Der Grund für ersteres ist leicht zu verstehen: Eine Schleife: for( i = 0; i < n; ++i ) tu irgendwas mit A[i] wird gerne durch Pointerarithmetik ersetzt: for( tmp = A; tmp < &A[n]; ++tmp ) tu irgendwas mit *tmp Nebeneffekt ist dabei, dass unmittelbar vor Schleifenabbruch tmp die Adresse von A[n] enthält. Will man aber das Array von der anderen Seite her abarbeiten for( i = n-1; i >= 0; --i ) tu irgendwas mit A[i] kann man das nicht analog in Pointerarithmetik umpfriemeln for( tmp = &A[n-1]; tmp >= A; --tmp ) tu irgendwas mit *tmp weil tmp am Ende den Wert &A[-1] annehmen würde, und alleine das Bilden dieses Wertes ist schon illegal. ad 2 Das ist dann ein signed unsigned mismatch. Wenn mich mein Gedächtnis nicht im Stich lässt, wird der signed Typ zum jeweils passenden unsigned Typ promoted. Wenn dein Rechner also 16 Bit 2-er Komplement Arithmetik benuzt, dann ist -1 > 33000U tatsächlich TRUE ad 3 Was soll passieren? Der Compiler ändert in der Berechnung den Datentyp. Aber abgesehen davon bleibt das Bitmuster unangetastet. Dasselbe Bitmuster das den signed Typ ausmacht wird dann als unsigned Typ interpretiert und damit weitergerechnet als ob es schon immer unsigned gewesen wäre.
Karl heinz Buchegger wrote: > for( tmp = &A[n-1]; tmp >= A; --tmp ) > tu irgendwas mit *tmp > > weil tmp am Ende den Wert &A[-1] annehmen würde, und alleine > das Bilden dieses Wertes ist schon illegal. Bei Harvard Architekturen (z.B. 8051) ist 0x0000 eine gültige Adresse und wird auch verwendet. 0x0000 - 1 ist dann 0xFFFF und die Schleife würde nie abgebrochen. Allerdings kann das auch nach oben hin passieren, wenn der SRAM bis zum letzten Byte ausgequetscht würde. Praktisch dürfte das kaum der Fall sein. Peter
Hier gehts nicht um Harvard oder nicht Harvard. Hier geht es darum, was dir der C-Standard zugesteht. Und der gesteht dir nun mal zu, dass int A[5]; int* b = &A[5]; legal ist und ein definierstes Ergebnis hat. Wohingegen b = &A[-1]; nicht legal ist. > Allerdings kann das auch nach oben hin passieren, wenn der SRAM bis zum > letzten Byte ausgequetscht würde. Genau diesen Fall muss der Compiler verhindern. Der Compiler muss das Array so legen, dass das nicht passiert. Er muss also sicherstellen, dass für type A[N] die Adresse &A[N] gebildet werden kann und dass &A[N] > &A[N-1] ist.
> Genau diesen Fall muss der Compiler verhindern
Nachtrag: Ob die meisten Compiler das wirklich tun, na ja, ich hab
da so meine Zweifel. Aber wenn er C-Standard konform ist,
müsste er.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.