Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Casting e comportamento indefinito
Forum - C/C++ - Casting e comportamento indefinito

Avatar
AldoBaldo (Member)
Guru


Messaggi: 708
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 18:48
Domenica, 31/12/2023
Ah, questa è proprio una domandona che voglio porre qui!

Nel tentativo di "isolare" le chiamate a winapi32 che si occupano di rilevare il tempo dal sistema, così da poter usare il tipo standard uint64_t invece del tipo proprietario di Windows FILETIME, sto mettendo insieme una mini-libreria statica da usare nei miei programmini.

Una delle funzioni è questa, che dovrebbe convertire una quantità di nanosecondi che esprime il tempo locale nella quantità di nanosecondi che esprime il tempo UTC equivalente:

Codice sorgente - presumibilmente C/C++

  1. uint64_t converti_nanosecondi_in_nanosecondi_UTC( uint64_t ns ) {
  2.     FILETIME lft = *((FILETIME*)&ns);
  3.     FILETIME ft = {0};
  4.  
  5.     if( LocalFileTimeToFileTime(&lft,&ft) )
  6.         return *((uint64_t*)&ft);
  7.  
  8.     return NANOSECONDI_NON_VALIDI;
  9. }



Ottengo un warning che dice: "dereferencing type-punned pointer will break strict-aliasing rules".

Ho fatto un po' di ricerche e credo di aver capito che si corre il rischio di generare comportamenti indefiniti conseguenti a un trattamento inaffidabile dei registri.

Ora, ho riscritto la funzione in quest'altro modo:

Codice sorgente - presumibilmente C/C++

  1. uint64_t converti_nanosecondi_in_nanosecondi_UTC( uint64_t ns ) {
  2.     uint64_t ft = 0;
  3.  
  4.     if( LocalFileTimeToFileTime((void*)&ns,(void*)&ft) )
  5.         return ft;
  6.  
  7.     return NANOSECONDI_NON_VALIDI;
  8. }



Con questa nuova formulazione il warning non mi viene più presentato, ma ho come la sensazione che la sostanza del "gioco" di puntatori non cambi, ripresentando lo stesso potenziale problema di prima, anche se "invisibile" al compilatore.

Che mi dite?



Per la cronaca: SYSTEMTIME è una struttura costituita da due DWORD, quindi dovrebbe occupare 64 bit.



ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 0:29
Martedì, 02/01/2024
La documentazione di Windows (https://learn.microsoft.com/en-us/windows/win32/api/minwinb ... sconsiglia di fare un cast in questa maniera:

Testo quotato


Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER* or __int64* value because it can cause alignment faults on 64-bit Windows.



Io per sicurezza definirei una union, copiando dwLowDateTime e dwHighDateTime.

Nota anche che dipendentemente dalla versione di C++ che stai utilizzando, non c'e' bisogno di usare le Win32 API, puoi usare chrono: https://en.cppreference.com/w/cpp/chrono

Ultima modifica effettuata da pierotofy il 02/01/2024 alle 0:35


Il mio blog: https://piero.dev
PM Quote
Avatar
AldoBaldo (Member)
Guru


Messaggi: 708
Iscritto: 08/01/2015

Segnala al moderatore
Postato alle 10:26
Martedì, 02/01/2024
Grazie Piero. Prima di leggere la tua risposta ho optato per questa soluzione:

Codice sorgente - presumibilmente C/C++

  1. static uint64_t converti_filetime_in_uint64( FILETIME ft ) {
  2.     return (((uint64_t)ft.dwHighDateTime)<<32)|((uint64_t)ft.dwLowDateTime);
  3. }



Magari si potrebbe trarne una macro, ma non so se sarebbe più o meno "conveniente".
Dici che usare una union sarebbe meglio?

Ah, per la cronaca, uso il più "classico" dei C, includendo stdint.h.


ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
PM Quote
Avatar
pierotofy (Admin)
Guru^2


Messaggi: 6230
Iscritto: 04/12/2003

Segnala al moderatore
Postato alle 21:26
Mercoledì, 03/01/2024
Penso la tua soluzione vada bene.


Il mio blog: https://piero.dev
PM Quote