www.mikrocontroller.net

Forum: Compiler & IDEs Ein paar kurze Fragen zu C


Autor: mr.chip (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.


Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.