Sincronizza Indice |
Scarica il progetto |
Testo dell'articolo |
Stampa l'articolo |
Difficoltà: 3 / 5 Nel corso base abbiamo introdotto la logica booleana, secondo la quale tutte le espressioni ricevono un risultato Vero o Falso ed abbiamo potuto approfondire l'algebra booleana nelle informazioni aggiuntive. È noto quindi a tutti che se un'espressione restituisce valore Vero, combinando tale espressione con l'operatore NOT otteniamo il valore Falso. Tutto vero se non esistessero le leggi di Murphy a capovolgere tutte le regole esistenti e conosciute nell'universo.
L'esempio trattato utilizza la funzione API SHFileOperation che necessita a sua volta di una struttura di nome SHFILEOPSTRUCT. La definizione di tale struttura è stata, purtroppo, molte volte errata anche da parte di Microsoft. La documentazione ufficiale MSDN infatti dichiara la struttura con:
E la trasporta quindi in Visual Basic come:
[ Tratto da How To Delete a File into the Win95 Recycle Bin (Q154005) ] Si tratta effettivamente di una svista di qualche sbadato programmatore, che è stata corretta successivamente con una postilla come questa, aggiunta in altri articoli sullo stesso argomento: "NOTE: The 32-bit version of Visual Basic aligns structures at double word boundaries, but some API functions, such as the SHFileOperation, expect the data to arrive as byte aligned". Tuttavia lo stesso errore è stato commesso da tantissimi altri programmatori che sottovalutavano il comportamento di Visual Basic nell'uso di tipi di dati definiti dall'utente, cosicché la precedente definizione di SHFILEOPSTRUCT si è diffusa notevolmente facendo passare l'errore inosservato.
Svilupperemo un semplicissimo progetto per dimostrare come un errore di questo genere può facilmente condurre a dubitare sulla correttezza delle regole di base dell'algebra booleana.
Le dichiarazioni riprendono la definizione precedente di SHFILEOPSTRUCT e vi aggiungono la dichiarazione della funzione API SHFileOperation che utilizza tale struttura.
All'avvio del programma sarà creato un file di testo di nome BLABLA.TXT e posto nella radice del disco C:. Questo non è il modo migliore di scrivere un file di testo ma è stata utilizzata la soluzione più semplice possibile. A tale scopo si consulti l'articolo riguardante la scrittura di un file di testo.
Alla riga 27 è richiamata la funzione SHFileOperation con la variabile udtFileOp che conterrà il percorso del file da eliminare (riga 25) e l'operazione richiesta è la cancellazione (riga 26). Quando viene richiesto di eliminare il file è fondamentale rispondere No. La funzione al suo ritorno dovrebbe pertanto indicare che l'utente ha annullato l'operazione ed è questo lo scopo del membro fAnyOperationsAborted della struttura e qui appare la stranezza.
Le due righe 28 e 29 dovrebbero dati risultati opposti. Mentre la prima, come detto restituisce valore Vero, la seconda dovrebbe riportare il risultato Falso, in ragione dell'operatore Not usato.
Purtroppo, come mostrano le due figure sovrastanti, in entrambi i casi il risulato è Vero. Sembra assurdo a dirsi ma il contrario di Vero è Vero. Esiste una spiegazione di questo comportamento a dir poco assurdo ed è legato all'errata dichiarazione della struttura SHFILEOPSTRUCT.
L'aver dichiarato il membro come Boolean limita le risposte a Vero e Falso che la variabile restituisce. Tuttavia l'operatore Not non valuta l'espressione prima di invertirla ma il linguaggio segue un percorso differente. L'operatore Not in realtà inverte tutti i bit della variabile
in questione (.fAnyOperationsAborted) ed il risultato è
riportato come espressione da valutare. Tuttavia, come abbiamo già detto, e come nel nostro caso, se la variabile non contiene il valore 0, il risultato booleano sarà comunque Vero. Nell'esempio precedente infatti la variabile .fAnyOperationsAborted assume valore 1 se l'utente ha annullato l'operazione; pertanto la negazione (l'inversione dei bit) del valore 1 (0000 0001) produce il valore -2 (1111 1110), la cui valutazione booleana corrisponde sempre a Vero. L'unico caso in cui il risultato è Falso avviene quando tutti i bit della variabile sono uguali a 0 e l'inversione produce il risultato contrario. Dopo
aver terminato l'uso dell'esempio mostrato in precedenza, ricordarsi di
eliminare manualmente oppure mediante il programma stesso il file C:\BLABLA.TXT. |
Questo esempio voleva dimostrare come un semplice errore nella dichiarazione può generare una serie di errore difficili da tracciare perché sintatticamente tutto appare corretto. Per concludere, la dichiarazione corretta della struttura SHFILEOPSTRUCT utilizza dei valori Long sia per il membro fFlags sia per il successivo fAnyOperationsAborted. Si raccomanda quindi di non fidarsi ciecamente delle dichiarazioni API copiate da qualche esempio ma, in caso di errori insoliti, verificare il valore di ciascun membro delle strutture API. Fibia
FBI
|
Torna all'indice delle Stranezze |