mikrocontroller.net

Forum: Compiler & IDEs char*char=int ?


Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich auf einem AVR (oder vermutlich auch den meisten anderen 8bit
uCern) zwei Bytes multipliziere bekomme ich ein Doppelbyte, also einen
int.
Wie ist das jetzt in C ?
Normalerweise wird doch nur mit den Datentypen gerechnet die vorhanden
sind, also char+char=char, int+char=int usw. und erst bei der Zuweisung
wird der Datenytp konvertiert.
Was passiert also, wenn ich int=char*char in C rechne, funktioniert das
oder muss ich vorher auf int casten (was ja eigentlich Schwachsinn wäre,
denn der Compiler rechnet dann int=int*char obwohl char*char ausreichen
würde.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> oder muss ich vorher auf int casten

Ja.

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mit WinAVR ist es egal ob am castet oder nicht, es wird ein int daraus,
das Ergebnis passt also.
volatile unsigned char x,y;
volatile unsigned int z;
z=x*y;

  67 0008 9981          ldd r25,Y+1
  68 000a 8A81          ldd r24,Y+2
  69 000c 989F          mul r25,r24
  70 000e C001          movw r24,r0
  71 0010 1124          clr r1
  72 0012 8B83          std Y+3,r24
  73 0014 9C83          std Y+4,r25

Ist das eine Eigenart von dem Compiler, oder gibt es irgendwie was
festgelegtes ?

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Komisch, bei shift-Operationen meckert der Compiler, wenn man nicht
vorher castet (was ja auch so sein muß) ...

unsigned char x = 0xAA;
x <<= 8;

Wird angemeckert.

unsigned char x = 0xAA;
unsigned int y = 0;
y = (unsigned int) x << 8;

Ist i.O.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jeder ANSI-C Compiler muss sich bei "char" Operationen so verhalten,
als ob beide Seiten der Operation erst nach "int" konvertiert werden
und danach gerechner wird. Das ist in C so definiert. Wenn's in der
Praxis auch kürzer geht und der Compiler spezielle Operationen auch
nutzt (8x8=16 MUL), dann ist das ok, wenn das Ergebnis muss zur
Definition passt.

Typische Falle in diesem Zusammenhang:
   uint8_t x;
   if (x+1 > 100)
Ein ANSI-C-Compiler muss das auch wirklich als 16-Bit Operation
durchführen. Weil's im Fall x=255 auf die Varianten (0 > 100) vs (256
> 100) rausläuft. Wer da unbedingt effizienten 8-Bit-Code haben will,
muss schreiben:
   if ((uint8_t)(x+1) > 100)

@Alex: Es bleibt dem Compiler unbenommen, Blödsinn auch als Blödsinn zu
bezeichnen, wenn er in der Lage ist, das zu erkennen.

Der erste Fall (x <<= 8) ist formal
    x = (char)( (int)x << 8 )
und damit wirkungsmässig identisch mit
    x = 0
Es spricht nichts dagegen, dass der Compiler das merkt. Muss er aber
nicht.

Der zweite Fall ist jedoch völlig in Ordnung.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Normalerweise wird doch nur mit den Datentypen gerechnet die vorhanden
sind, also char+char=char, int+char=int usw. und erst bei der Zuweisung
wird der Datenytp konvertiert."

Nein.

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@A.K.

Könntest du diese letzte Behaupt etwas genauer erklären ?

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Benedikt: Habe ich doch oben geschrieben: Jeder ANSI-C Compiler muss
sich bei "char" Operationen so verhalten, als ob beide Seiten der
Operation erst nach "int" konvertiert werden und danach gerechner
wird. Ist seit K&R so festgelegt und wurde weder von ANSI noch von C++
geändert.

Historischer Hintergrund: C ist für die PDP-11 entstanden und die
Byte-Operationen der PDP-11 arbeiten so.

Der Compiler kann natürlich a=b+c immer noch 8bittig rechnen, denn wenn
a,b,c 8bittig sind, kommt exakt das gleiche dabei heraus.

Es gibt freilich Compiler, die dieses Verhalten abschaltbar machen
(z.B. Keil), weil's auf 8bittern etwas ineffizient ist.

Näheres dazu siehe C-Handbuch.

Autor: Benedikt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Abgesehen von der char/int Ausnahme, gilt meine Aussage jedoch, oder ?

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welche Aussage? Von derjenigen abgesehen, die ich bereits kommentierte,
finde ich keine.

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C Handbuch siehe "type coercion" oder "usual arithmetic
conversions". Hab's nicht auf deutsch parat, sorry.

Kurzform: Es werden sowohl die Operanden aneinander angepasst
erweitert, als auch das Ergebnis anschliessend an den Typ des
Zieloperandens erweitert oder reduziert. Die Operation findet
mindestens als "int" oder "unsigned" statt, char/short-Werte werden
entsprechen erweitert.

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.