In zlib 1.2.7, Datei inffast.c, Linie 320, gibt es eine Aussage, die ich nicht verstehe:Warum versucht zlib nur eine positive Zeigerdifferenz zu berechnen?
strm->avail_out = (unsigned)(out < end ?
257 + (end - out) : 257 - (out - end));
Variablen end
und out
sind zwei Zeiger in den Ausgabepuffer. Diese Aussage macht eine Anstrengung, end - out
zu berechnen, wenn end > out
und out - end
wenn out >= end
, aber ich sehe nicht, warum es das tun könnte. Es scheint mir, dass das Endergebnis das gleiche ist, das heißt, könnte die Linie als gut geschrieben worden ist:
strm->avail_out = 257 + (end - out);
Die Differenz von zwei Zeigern hat einen gezeichneten integralen Typen, ptrdiff_t
(C99 6.5.6: 9) und 257
hat den Typ int
. Die Addition findet in der Art des höheren Rangs zwischen diesen beiden statt, und ich sehe nicht, wovor der ternäre Operator möglicherweise schützen könnte.
Ich würde mich nicht wundern, wenn die berühmte Portabilität von zlib auch dadurch möglich gemacht wurde, dass * * * nicht auf definiertem Verhalten beruhte, sondern vielmehr überprüft wurde, was die Implementierungen tatsächlich tun. –
Gibt es einen Quellcode Repo mit genug Geschichte, um diese Linie zu beschuldigen und zu sehen, ob es sich von einer anderen Formulierung entwickelt hat? – Potatoswatter
@Potatoswatter Das einzige, was ich gefunden habe, ist in der "Änderungshistorie" in inflate.c "Ändere strm-> next_out [-state-> offset] zu * (strm-> next_out - state-> offset), um Negationsprobleme zu vermeiden Alphas (64 Bit) in inflate.c "aber das erklärt es nicht. Ich kann sehen, wie 'p [-o]' sich von '* (p-o)' mit 'o' einem 32-Bit unsigned int und' p' einem 64-bit Zeiger unterscheiden könnte. Die Aussage in meiner Frage ist etwas anderes. –