mikrocontroller.net

Forum: Compiler & IDEs Überlauf von int, char etc.


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ist eigentlich im C-Standard festgelegt, was bei einem Überlauf der
verschiedenen Datentypen als nächster Wert herauskommt?
Also was für ein Wert erhalte ich nach einem Überlauf durch z.b. i++
bei:

int
unsigned int
char
unsigned char

Ich brauche in einem Timerinterrupt einen Zähler der immer durchläuft.
Oder sollte man des Stils wegen auf die Einhaltung des Wertebereichs
prüfen und dann manuell wieder von vorn beginnen?

Autor: Wolfgang Horn (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, Thomas,

wenn Du aufwärts zählst und am Ende des Wertebereiches angekommen bist,
dann führt der nächste Schritt ans andere Ende.

Srell Dir den Wertebereich wie das Zifferblatt einer Uhr vor - nach 23
Uhr kommt 0 Uhr.

Dein Zähler läuft also sowieso immer durch.

Gelegentlich kann man Überlauf nicht brauchen. Dann nehme ich zwei
Variablen, die ich beide auf diesem Ziffernblatt um 90° versetzt
weiterzähle.

Ciao
Wolfgang Horn

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ist eigentlich im C-Standard festgelegt, was bei einem Überlauf
> der verschiedenen Datentypen als nächster Wert herauskommt?

Bei vorzeichenlosen ja. Da werden alle Berechnungen immer Modulo
2 hoch Bitzahl durchgeführt. Wenn man oben rausläuft, kommt man unten
wieder rein. Bei den Typen mit Vorzeichen ist es undefiniert.

> Also was für ein Wert erhalte ich nach einem Überlauf durch z.b.
> i++ bei:
>
> int

undefiniert

> unsigned int

0

> char

implementationsspezifisch

> unsigned char

0

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"ist eigentlich im C-Standard festgelegt, was bei einem Überlauf der
verschiedenen Datentypen als nächster Wert herauskommt?"

Ber Typen ohne Vorzeichen ja. Modulo (<maximaler Wert>+1). Ist das was
man intuitiv auch erwartet.

Bei Typen mit Vorzeichen ist das Verhalten bei Überlauf offiziell
undefiniert.

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch ne Gemeinheit, bei int ist die Länge undefiniert.

Statt int sollte man daher besser short (16Bit) nehmen, da auf
32Bittern int = long (32Bit) ist.


Peter

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Noch ne Gemeinheit, bei int ist die Länge undefiniert.

Generell ist bei allen ,,allgemeinen Typen'' die Länge undefiniert.
Es gibt nur Mindestanforderungen an die Genauigkeit, die bei unseren
üblichen Zweierkomplementdarstellungen und IEEE754-Gleitkommazahlen
folgendes implizieren:

. sizeof(char) >= 8
. sizeof(short) >= 16
. sizeof(int) >= 16
. sizeof(long) >= 32
. sizeof(long long) >= 64
. sizeof(float) >= 32
. sizeof(double) > 32

(Letzteres wird vom AVR-GCC derzeit nicht eingehalten.)

> Statt int sollte man daher besser short (16Bit) nehmen, da auf
> 32Bittern int = long (32Bit) ist.

Nein, wenn man Typen mit expliziten Längen haben möchte, sollte man
auch Typen mit expliziten Längen benutzen, statt implizite Annahmen
zu treffen.  Diese sind (per C99) in <stdint.h> definiert.  Wenn eine
Maschine dann z. B. keinen 8-Bit-Datentyp kennt (soll's bei einigen
DSPs geben), dann bekommt man wenigstens saubere Fehler beim Versuch,
int8_t oder uint8_t zu benutzen (die gibt's dort dann nicht), statt
irgendwelcher Überraschungen, weil der Programmierer implizit
angenommen hat, dass sein "unsigned char" genau 8 Bits lang wäre und
von 255 nach 0 umschlägt.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Immerhin gibt es auch eine Headerdatei, die die Grenzen der vor C99
definierten Datentypen beschreibt - limits.h

Auszug aus limits.h des mit Rowley Crossworks for ARM gelieferten gcc:
#define CHAR_BIT   8
#define CHAR_MAX   255
#define CHAR_MIN   0
#define SCHAR_MAX  127
#define SCHAR_MIN  (-128)
#define UCHAR_MAX  255
#define SHRT_MAX   32767
#define SHRT_MIN   (-32767 - 1)
#define USHRT_MAX  65535

#if defined(__CROSSWORKS_MSP430) || defined(__CROSSWORKS_AVR) ||
defined(__CROSSWORKS_MAXQ)
#define INT_MAX   32767
#define INT_MIN   (-32767 - 1)
#define UINT_MAX  65535
#else
#define INT_MAX    2147483647
#define INT_MIN     (-2147483647 - 1)
#define UINT_MAX   4294967295
#endif

#define LONG_MAX   2147483647
#define LONG_MIN   (-2147483647 - 1)
#define ULONG_MAX  4294967295
#define LLONG_MIN  (-9223372036854775807LL - 1)
#define LLONG_MAX  9223372036854775807LL
#define ULLONG_MAX 18446744073709551615ULL

Damit kann man sich also auch mit nicht-C99-Compilern behelfen; eine
vergleichbare Datei existiert beispielsweise auch bei MS-Compilern, die
älter sind als C99.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Noch ne Gemeinheit, bei int ist die Länge undefiniert.

Sie ist nicht undefiniert, sondern implementationsspezifisch.

> Statt int sollte man daher besser short (16Bit) nehmen, da auf
> 32Bittern int = long (32Bit) ist.

short und long sind genauso implementationsspezifisch wie int.


Zur Ergänzung von Rufus' Posting:

C99 bietet mit stdint.h einen Header, der typedefs unter anderem für
Integertypen mit festen Größen bietet.
Es ist übrigens ein Armutszeugnis für die Compilerhersteller, wenn sie
es nach 7 Jahren immer noch nicht geschafft haben, halbwegs
ISO-konforme Compiler zu bauen. C89 ist keine Norm, denn es wurde mit
Erscheinen von C99 offiziell ungültig.

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.