Wie bemerkt in den Kommentaren, die Makrodefinition Sie präsentieren sich nicht ausdehnt, um gültige C-Code, weil es Computing beinhaltet (char*)0 % sizeof(long)
, wo der linke Operand des %
Typ char *
hat. Das ist kein Integer-Typ, aber beide Operanden von %
müssen einen Integer-Typ haben.
Außerdem hat die Makroerweiterung unsymmetrische Klammern. Das ist nicht inhärent falsch, aber es macht das Makro schwierig zu bedienen. Selbst wenn die Vorrangstellung des Operators ein vernünftiges Ergebnis ergibt, kann die Verwendung von Klammern und zusätzlichen Leerzeichen die menschliche Interpretation des Codes unterstützen, ohne die Ausführungsgeschwindigkeit zu beeinträchtigen und die zusätzlichen Kompilierungskosten vernachlässigen.
Also, ich glaube, das gewünschte Makro eher wie dieses wäre:
#define SWAPINT(a,es) swaptype = ( \
((((char*)a - (char*)0) % sizeof(long)) || (es % sizeof(long))) \
? 2 \
: ((es == sizeof(long)) ? 0 : 1)) \
)
ich stattdessen betrachten würde die vorletzte Zeile als
: (es != sizeof(long))
Schreiben der Komplexität des Ausdrucks auf eine reduzieren leichte Kosten für seine Verständlichkeit.In jedem Fall scheint die Absicht swaptype
zu setzen zu sein: auf einer n
-Byte Grenze
2
wenn a
ist nicht ausgerichtet sind, wobei n
die Anzahl der Bytes in einem long
ist oder wenn es
ist kein ganzzahliges Vielfaches der Größe eines long
; ansonsten
1
wenn es
ungleich der Größe eines long
ist; sonst
0
Das ist ähnlich, aber nicht identisch sind, auf Ihre Interpretation. Beachten Sie jedoch, dass auch dieser Code aufgrund von (char*)a - (char*)0
ein undefiniertes Verhalten aufweist. Die Auswertung dieses Unterschieds hat das Verhalten nur dann definiert, wenn beide Zeiger auf dasselbe Objekt oder kurz nach dem Ende desselben Objekts zeigen, und (char *)0
nicht auf das Ende eines Objekts zeigt.
Sie ausdrücklich gefragt:
Aber ich verstehe nicht, warum Typumwandlung implementiert ist, (char *) ein.
, die durchgeführt wird, weil die Zeigerarithmetik in Bezug auf dem spitzen-geben, so definiert ist, (1) kann ein konformes Programm nicht Arithmetik durchführt mit einem void *
, und (2) möge der Code das Ergebnis der Subtraktion in den gleichen Einheiten wie das Ergebnis des Operators sizeof
(Bytes) sein.
Und was bedeutet diese Linie?
(char*)a- (char*)0)% sizeof(long)==1
Diese Zeile erscheint nicht in dem Makro Sie präsentiert, und es ist kein vollständiger Ausdruck wegen der unausgeglichenen Klammern. Es scheint zu versuchen, zu bestimmen, ob a
Punkte hinter einer n
-Byte-Grenze zeigt, wobei n
wie oben definiert ist, aber wiederum hat die Auswertung der Zeigerdifferenz ein undefiniertes Verhalten. Beachten Sie auch, dass für eine ganze Zahl x
, x % sizeof(long) == 1
im booleschen Kontext ausgewertet hat eine andere Bedeutung als x % sizeof(long)
im gleichen Kontext ausgewertet. Letzteres macht in dem von Ihnen beschriebenen Kontext mehr Sinn.
Dieser Code scheint ziemlich gebrochen. Es gibt mindestens einen Syntaxfehler im Makro, eine fehlende Klammer. Auch, (char *) a - (char *) 0 sollte ein No-Op sein, es sei denn, etwas fehlt mir? Wie sollte (char *) 0% sizeof (lang). – jforberg
'(char *) 0% sizeof (long)' macht nicht einmal Sinn, weil ein Zeigertyp kein arithmetischer Typ ist. Was auch immer das ist, dies entspricht nicht C. Wo haben Sie diesen Code gefunden? Und bist du sicher, dass du es richtig kopiert hast? –
'%' beats '-' so' (char *) a- (char *) 0% sizeof (lang) 'ist' (char *) a - ((char *) 0% sizeof (lang)) '. Sicherlich wurde ((char *) a- (char *) 0)% sizeof (long) 'gewünscht. – chux