Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Was macht dieser Code?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
09.02.2009, 15:28 Uhr
~Dirk_Gast
Gast


Hallo,

ich habe gerade folgendes Makro vor mir und verstehe es leider überhaupt nicht.

l ist ein unsigned long und c ein unsigned char Zeiger.


C++:
#define HOST_l2c(l,c)    (*((c)++)=(unsigned char)(((l)    )&0xff),    \
             *((c)++)=(unsigned char)(((l)>> 8)&0xff),    \
             *((c)++)=(unsigned char)(((l)>>16)&0xff),    \
             *((c)++)=(unsigned char)(((l)>>24)&0xff),    \
             l)



Was macht der Komma-Operator hier? Was passiert hier?

Vielen Dank
Dirk
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
09.02.2009, 16:20 Uhr
~kronos
Gast


Der Code schreibt das niederwertigste Byte von l in c[0], das zweitniedrigste in c[1] usw.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
09.02.2009, 16:50 Uhr
ao

(Operator)


Ist das sicher?

Ich meine, ist beim Komma definiert, dass der linke Ausdruck vor dem rechten ausgewertet wird? Falls es umgekehrt ist, ist das Ergebnis gespiegelt.

Allein schon, weil man diese Feinheiten wissen muss, finde ich solchen Code blöd ...
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
09.02.2009, 16:56 Uhr
Kest
saint



Zitat von ao:
Ich meine, ist beim Komma definiert, dass der linke Ausdruck vor dem rechten ausgewertet wird?

Wenn C++, dann ja: bei Operatoren Komma, logisches Und, logisches Oder wird der linke Operand vor dem rechten ausgewertet.
--
Wenn man einen Hufschlag hört, sollte man >Pferd< denken und nicht >Zebra<.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
09.02.2009, 17:39 Uhr
kronos
Quotenfisch
(Operator)



Zitat von Kest:
Wenn C++, dann ja: bei Operatoren Komma, logisches Und, logisches Oder wird der linke Operand vor dem rechten ausgewertet.

In C etwa nicht?

Zur näheren Erklärung: 0xff ist ein Bzte voller Einsen, l & 0xff liefert darum den Wert des untersten Bztes von l. In der nächsten Zeile wird l um 8 Bit verschoben und c ist durch das ++ um ein Bzte weiter gerückt etc.

Weitere Gründe den Code blöd zu finden:
- Das Makro verändert c, d.h. nach Anwendung des Makros muss man wieder 4 abziehen um den ursprünglichen Pointer zu erhalten.
- long ist nicht immer 4 Bzte lang
- ein
C++:
char c[sizeof(long)];
*((long*)c)=l;

wäre einfacher und übersichtlicher
--
main($)??<-$<='?'>>2?main($-!!putchar(
(("$;99M?GD??(??/x0d??/a:???;a"+'?'/4)
??($??)+'?'/3-2-1+$%2)??''?')):'?';??>

Dieser Post wurde am 09.02.2009 um 17:40 Uhr von kronos editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
09.02.2009, 18:38 Uhr
0xdeadbeef
Gott
(Operator)


Es wird hier wohl um Netzwerkübertragung oder etwas vergleichbares gehen, das Makro wandelt auf einer 32bit-Maschine einen unsigned long nach big endian.

Da das vor allem für Interoperabilität zwischen verschiedenen Rechnerarchitekturen von Bedeutung ist, wäre allerdings die Benutzung der Typen konstanter Breite sinnvoller, also uint32_t statt unsigned long. Und natürlich sollte man das ganze als Funktion schreiben, nicht als Makro. Wobei, wenn wir schon dabei sind, am sinnvollsten wäre

C++:
#include <arpa/inet.h>


...und die Benutzung von htonl bzw. ntohl.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
16.02.2009, 20:15 Uhr
xXx
Devil


Bin ich gerade verballert oder is *((c)++) so ziemlich umständlich für *++(c) ?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
16.02.2009, 20:47 Uhr
0xdeadbeef
Gott
(Operator)


Du bist gerade verballert.

Klammern der Einfachheit mal weggelassen, *c++ ist etwa das selbe wie ++c,*(c-1). Dagegen ist *++c das selbe wie ++c,*c
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
28.02.2009, 13:26 Uhr
xXx
Devil


Hm aber sollte nicht durch die Klammern erst der Ausdruck darin interpretiert werden? Sonst is schon klar wo der unterschied zwischen Post u. Pre-Inkrementierung ist :P
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
01.03.2009, 02:58 Uhr
0xdeadbeef
Gott
(Operator)


Hmm...so halb. ++ bindet stärker als *, dementsprechend ist *c++ das selbe wie *(c++), der Rückgabewert von c++ muss also konsequenterweise vor der Auswertung von * bestimmt werden. Allerdings hat c++ zusätzlich zum Wert noch eine Nebenwirkung, nämlich die nachträgliche Erhöhung des Wertes von c, und von der ist lediglich garantiert, dass sie bis zum nächsten Sequenzpunkt ausgeführt wird. Klammern sind keine Sequenzpunkte (und selbst wenn sie es wären, wäre der Wert von c++ immer noch c vor der Erhöhung).

Das ist übrigens, wo ich gerade darüber nachdenke, auch ein Unterschied zwischen ++c,*(c-1) - dies enthält mit dem Komma einen Sequenzpunkt.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 01.03.2009 um 02:59 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: