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.