Forum: Compiler & IDEs char nicht kleiner null ?


von Eddi (Gast)


Lesenswert?

Ich hab hier folgende Routine um Zahlen auf einem LCD auszugeben :

void val2lcd(unsigned char xpos, unsigned char ypos, char val)
{
unsigned char temp[4];

  temp[0] = ' ';
  temp[1] = ' ';
  if (val < 0) {
    temp[0] = '-';
    val = val * -1;
  }
  if (val > 99) temp[0] = '0' + val / 100 % 10;
  if (val >  9) temp[1] = '0' + val / 10 % 10;
  temp[2] = '0' + val % 10;
  temp[3] = 0;
  lcd_goto(xpos,ypos);
  lcd_write_string(temp);
}

In der Zeile "if (val < 0) {" meckert WinAVR aber und sagt :

"messages.c:12: warning: comparison is always false due to limited
range of data type"

Kann ein char beim AVR nicht negativ sein ? Auf einem 8051er laeuft die
gleice Routine ohne Probleme.

verwirrte Grüsse
Eddi

von Alex (Gast)


Lesenswert?

Vielleicht muss man ein "signed" davor schreiben?!

von Matthias (Gast)


Lesenswert?

Hi

IIRC ist im C Standard nicht vorgegeben ob ein char signed oder
unsigned ist. Das bleibt der Implementierung überlassen. Beim GCC ist
es AFAIK so das ein char unsigned ist.

Macht auch Sinn da sich mit unsigned einfacher rechnen läßt.

Matthias

von Jörg Wunsch (Gast)


Lesenswert?

Eigentlich ist das default `char' beim AVR-GCC signed, aber man kann
das auch von der Kommanodzeile überschreiben.

Da hier aber offenbar gar kein character (im Sinne eines auszugebenden
Zeichens) gewünscht ist, sondern eine kleine integer-Zahl, ist es m.E.
sinnvoller,

#include <inttypes.h>

und int8_t zu benutzen.

von Eddi (Gast)


Lesenswert?

Kann ich dem Compiler denn beibringen, dass mein char signed ist, oder
muss ich dann auf int umsteigen ?

So langsam glaube ich, ich haette bei Assembler bleiben sollen g

Eddi

von Eddi (Gast)


Lesenswert?

Danke Jörg,

jetzt klappt's auch mit der Temperatur...


Eddi

von nobody0 (Gast)


Lesenswert?

Tja, auf PC ist beim gcc char gleich signed char, aber auf ARM ist char
gleich unsigned char, so dass ich von PC-gcc zu ARM-gcc portieren
mußte.

Der ANSI-Standard definiert deshalb in stdint.h einige davon (aber
nicht von der Endianess) unabhängige Datentypen: uint8_t, int8_t, ....
Allerdings nützt das nix, wenn man Funktionen wie printf und strncmp
verwendet, denn die arbeiten mit dem plattformabhängigen char.

von Helmut Weiß (Gast)


Lesenswert?

Hallo Eddi,

laß Dich nicht entmutigen. Es sollte jemand sagen, daß man bei der
Deklaration einer Variablen entweder signed char (-128 bis +127) oder
unsigned char (0 bis 255) vor die char-Variable schreiben kann. Dann
ist es egal welche Voreinstellung der Compiler hat. Größere Werte
erfordern int oder long, die auch jeweils signed oder unsigned sein
können. Dann gibt es noch float, usw...

Eine Bitte an die anderen Kollegen: vergrault doch nicht einen
C-Anfänger. Jeder hat doch mal klein angefangen.

Viele Grüße

Helmut Weiß

von Jörg Wunsch (Gast)


Lesenswert?

Helmut, was willst Du?  Erstens ist das mit dem `signed' schon
geschrieben worden (bitte lies nach), zweitens halte ich die Variante
mit int8_t dennoch für vernünftiger, da sie eben genau sagt, was Du
haben möchtest: eine vorzeichenbehaftete Zahl mit 8 Bits.  Dafür
definiert der Standard schließlich diese Datentypen.  (Eddi hat's ja
offenbar damit auch erfolgreich gemacht -- wie kommst Du also auf
,vergraulen'?)

von Helmut Weiß (Gast)


Lesenswert?

Was sagen denn Kernighan und Ritchie zu int9_t. Die haben ja schließlich
das Standardwerk "The C-Programming Language" (1978) geschrieben.
Sicher ist in C erlaubt, was gefällt. Aber ist nicht ein Standard
(char, int und Co)besser zu verstehen, wenn er dazu noch in einem
Handbuch nachzulesen ist, daß allgemeine Gültigkeit hat, auch heute
noch.
Und dieses Buch ist nun mal die C-Bibel!

Viele Grüße,

Helmut Weiß

von Jörg Wunsch (Gast)


Lesenswert?

Es wäre endlich mal eine dritte Auflage des K&R fällig, die den
C99-Standard umfaßt.  Zur Erinnerung: die erste Auflage hat den
sogenannten "K&R-Standard" beschrieben, also den de-facto Standard
bis
zur wirklichen Standardisierung.  Die zweite Auflage hat der dann
stattgefundenen Standardisierung als ANSI-C 1989 Rechnung getragen
(alias ISO-C90).  Mittlerweile ist ISO-C99 aber das Aktuelle, K&R hin,
K&R her.

C99 ist Standard.  int8_t gehört zu C99.  Allemal besser als all die
selbgezimmerten u08 usw. Datentypen.

von Eddi (Gast)


Lesenswert?

Jungs !!!!

Locker bleiben... Am Ende zaehlt doch mehr das Ergebnis, zumindest im
Hobbybereich. Ich hab jetzt 3 Varianten probiert (int8_t, signed char
und Compilerflag) und hab mich fuer letztere entschieden, da ich schon
exsessiven Gebrauch von "unsigned char" in meinen Sourcen gemacht
habe. Ausserdem laesst es sich so besser zwischen AVR und 8051
wechseln.

Also : Ich denke, so wie jeder mag. Das sollte hier nicht in eine
Grundsatzdiskussion ausarten.

In diesem Sinne...

Eddi

von nobody0 (Gast)


Lesenswert?

K&R hat mit ANSI-C nur wenig zu tun; beispielsweise fehlen komplexe
Zahlen, sequence points und NaN habe ich da noch nicht gesehen.
Im K&R-Buch ist vom ANSI-C nur ca. 1/4.
Am Besten kauft man sich, nach dem Buch C-FAQs, den ANSI-Standard von
www.ansi.org; der kostet nur rund 14 EUR ;-) Das Rationale dazu ist
auch lesenswert.

Im Standard findet man interessante Sachen wie Compiler, bei denen alle
Variablen als volatile behandelt werden. Das erklärt den meist
mieserablen Microcompiler-Code, den man vielfach findet und der kein
bischen portabel ist, weil der unter anderen (ANSI-C-) Compilern nicht
funktionert.
Dass diese Compiler auf dem Stand von 1990 sind und selbst einfache
features wie den qualifier restrict nicht haben ist da noch ein kleines
Problem.

von OldBug (Gast)


Lesenswert?

>...da ich schon exsessiven Gebrauch von "unsigned char"
>in meinen Sourcen gemacht habe...

Wenn Du "unsigned char" verwendest, wird Dir kein Compilerflag helfen
können, da Du explizit angibst, daß der Wert in dieser Variablen nicht
kleiner als null (0) werden kann.

von Eddi (Gast)


Lesenswert?

Schon klar, deswegen hatte ich das ja an genau der besagten Stelle als
"char" definiert.

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
Noch kein Account? Hier anmelden.