Blog gunsmoker (traduceri) de ce valorile returnate-descriptori sunt atât de incoerente

De ce sunt descriptorii valorii returnate atât de incoerenți?

De ce sunt atât de diferite valorile de retur?

Motivele, după cum deja suspectați, sunt istorice.

Aceste valori au fost alese pe baza considerațiilor de compatibilitate cu Windows pe 16 biți. Funcția OpenFile 16 biți, _lcreat _lopen și se întoarce -1 dacă o eroare, astfel încât funcția CreateFile 32-bit returnează de asemenea -1 (INVALID_HANDLE_VALUE), pentru a ușura migrația de aplicare cu Win16.

(Deținând aceste informații, puteți răspunde deja următoarea întrebare simplă: de ce, atunci când am nevoie pentru a apela CreateFile, dar în realitate nu deschide fișierul nu ar trebui să funcționeze numit OpenFile Răspuns: Da, OpenFile ar fi un nume mai adecvat, dar Numele este deja luat.)

Pe de altă parte, Win16 nu avea echivalente pentru CreateThread sau CreateMutex, așa că revin 0.

Din moment ce un precedent incoerență deja stabilit valori returnate, cu adăugarea unei noi funcții obține întotdeauna o alegere între returnarea 0 sau INVALID_HANDLE_VALUE.

Această neconcordanță are mai multe consecințe.

În primul rând, bineînțeles, trebuie să verificați cu atenție valorile returnate.

În al doilea rând. acest lucru înseamnă că dacă doriți să scrieți un fel de înveliș general în jurul valorii de descriptor - atunci trebuie să faceți distincția între două valori posibile, "nu un descriptor".

În al treilea rând, dacă doriți să inițializa valoarea mâner, atunci trebuie să o faci în moduri diferite, în funcție de funcția cu care aveți de gând să-l folosească. De exemplu, următorul cod este incorect:
În acest cod există două bug-uri. În primul rând, valoarea returnată din valoarea CreateFile nu este validată corect. Codul de mai sus verifică pentru 0 în loc de INVALID_HANDLE_VALUE. În al doilea rând, codul inițializează incorect variabila H. Aici este versiunea corectată:
În al patrulea rând, trebuie să fie deosebit de atent cu valoarea INVALID_HANDLE_VALUE: pur întâmplător, coincide cu valoarea pseudo-a revenit GetCurrentProcess descriptor. Multe funcții de kernel ia astfel de pseudo-mânere, așa că, dacă, de exemplu, cu șurub și accidental apel, de exemplu, cu o valoare de WaitForSingleObject INVALID_HANDLE_VALUE, în cele din urmă veți găsi că așteptați pentru procesul de curent. Această așteptare, bineînțeles, nu se va termina niciodată, pentru că procesul intră într-o stare de semnal numai când ieșiți, așa că veți termina să vă așteptați.

Articole similare