2013-01-17 4 views
12

In zlib 1.2.7, inffast.c di file, la linea 320, v'è una dichiarazione che non capisco:Perché zlib si impegna a calcolare solo una differenza di puntatore positiva?

strm->avail_out = (unsigned)(out < end ? 
          257 + (end - out) : 257 - (out - end)); 

Variabili end e out sono due puntatori nel buffer di uscita. Questa dichiarazione compie uno sforzo per calcolare end - out quando end > out e out - end quando out >= end, ma non vedo perché potrebbe voler farlo. Mi sembra che il risultato finale è lo stesso, vale a dire, la linea potrebbe anche essere stato scritto:

strm->avail_out = 257 + (end - out); 

La differenza di due puntatori ha un tipo integrale firmato, ptrdiff_t (C99 6.5.6: 9) e 257 ha il tipo int. L'addizione avviene nel tipo di rango più alto tra questi due, e non vedo a cosa possa stare a guardia l'operatore ternario.

+3

Non sarei sorpreso se la famosa portabilità di zlib fosse resa possibile anche da * non * basandosi su un comportamento definito ma piuttosto controllando ciò che effettivamente fanno le implementazioni. –

+1

Esiste un repository del codice sorgente con una cronologia sufficiente per dare la colpa a questa linea e vedere se si è evoluta da una formulazione diversa? – Potatoswatter

+1

@Potatoswatter L'unica cosa che ho trovato è nella "Cronologia delle modifiche" in inflate.c "Modifica strm-> next_out [-state-> offset] su * (strm-> next_out - state-> offset) per evitare problemi di negazione su Alpha (64 bit) in inflate.c "ma questo non lo spiega. Posso vedere come 'p [-o]' potrebbe essere diverso da '* (p-o)' con 'o' un int con unsigned a 32 bit e' p' un puntatore a 64 bit. L'affermazione nella mia domanda è un'altra cosa. –

risposta

17

L'osservazione è corretta per C99 e C89/C90.

Questa riga di codice è stata scritta dieci anni fa. A questo punto, la mia memoria mi consente solo di essere in grado di rivendicare la paranoia come scusa. Apparentemente ero preoccupato che in alcuni compilatori il risultato della sottrazione di due puntatori potesse essere non firmato. Non ricordo l'origine di tale preoccupazione, o se avesse alcuna base.

Per quanto riguarda lo change history, quella linea di codice è nata dalla fronte di Zeus come la vedi oggi. Non è stato cambiato da quando è stato scritto.

Problemi correlati