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.