trabocca in aggiunte size_t
-
03-07-2019 - |
Domanda
Mi piace avere il mio codice gratuito di avviso per VS.NET e GCC, e mi piace avere il mio codice pronto per 64 bit.
Oggi ho scritto un piccolo modulo che si occupa di buffer di memoria e fornisce accesso ai dati tramite un'interfaccia in stile file (ad esempio puoi leggere byte, scrivere byte, cercare in giro ecc.).
Come tipo di dati per la posizione e la dimensione di lettura correnti ho usato size_t poiché questa sembra essere la scelta più naturale. Ottengo gli avvisi e dovrebbe funzionare anche a 64 bit.
Per ogni evenienza: la mia struttura è simile alla seguente:
typedef struct
{
unsigned char * m_Data;
size_t m_CurrentReadPosition;
size_t m_DataSize;
} MyMemoryFile;
La firma di size_t
sembra non essere definita nella pratica. Una ricerca del codice di Google lo ha dimostrato.
Ora sono in un dilemma: voglio controllare le aggiunte con <=> per overflow perché devo occuparmi dei dati forniti dagli utenti e le librerie di terze parti useranno il mio codice. Tuttavia, per il controllo di overflow devo conoscere la significatività. Fa un'enorme differenza nell'attuazione.
Quindi - come diavolo dovrei scrivere un tale codice in modo indipendente dalla piattaforma e dal compilatore?
Posso verificare la firma di <=> in fase di esecuzione o in fase di compilazione? Ciò risolverebbe il mio problema. O forse <=> non è stata la migliore idea in primo luogo.
Qualche idea?
MODIFICA : sto cercando una soluzione per il linguaggio C!
Soluzione
Per quanto riguarda se size
_ t è firmato o non firmato e GCC (da un vecchio manuale di GCC - non sono sicuro che sia ancora lì):
Esiste un potenziale problema con
size_t
tipo e versioni di GCC precedenti rilasciare 2.4. ANSI C lo richiedestddef.h
sii sempre un tipo senza segno. Per compatibilità con i sistemi esistenti file di intestazione, GCC definiscesys/types.h
inptrdiff_t
per essere qualunque tipo il il sistemassize_t
lo definisce essere. La maggior parte dei sistemi Unix che definiscono <=> in <=>, definiscilo in essere un tipo firmato. Qualche codice nel la libreria dipende dal fatto che <=> sia un tipo senza segno e non funzionerà correttamente se è firmato.Il codice della libreria GNU C che si aspetta <=> essere unsigned è corretto. Il definizione di <=> come tipo firmato non è corretto. Lo prevediamo nella versione 2.4, GCC definirà sempre <=> come un tipo senza segno e il la sceneggiatura di "fixincludes" massaggerà il sistema <=> per non farlo in conflitto con questo.
Nel frattempo, ci aggiriamo problema dicendo esplicitamente a GCC utilizzare un tipo senza segno per <=> quando compilando la libreria GNU C. 'configure' rileverà automaticamente quale tipo GCC utilizza per <=> organizzare per sovrascriverlo se necessario.
Se vuoi una versione firmata di <=> usa <=> o su alcuni sistemi c'è un typedef per <=>.
Altri suggerimenti
size_t
è un tipo integrale senza segno, secondo gli standard C ++ C. Qualsiasi implementazione che ha if (a + b < a)
firmato è seriamente non conforme e probabilmente ha anche altri problemi di portabilità. È garantito che si verifichi un overflow quando trabocca, il che significa che è possibile scrivere test come <=> per trovare l'overflow.
<=> è un tipo eccellente per tutto ciò che riguarda la memoria. Lo stai facendo bene.
size_t
deve essere senza segno.
In genere è definito come unsigned long.
Non l'ho mai visto definito diversamente. ssize_t
è la sua controparte firmata.
EDIT: GCC lo definisce come firmato in alcune circostanze. la compilazione in modalità ASNI C o std-99 dovrebbe costringerlo a essere senza segno.
Per il linguaggio C, utilizzare IntSafe . Rilasciato anche da Microsoft (da non confondere con la libreria C ++ SafeInt). IntSafe è un insieme di chiamate di funzioni in linguaggio C che possono eseguire operazioni matematiche e conversioni in modo sicuro. URL aggiornato per le funzioni intsafe
Usa safeint . È una classe progettata da Michael Howard e rilasciata come open source da Microsoft. È progettato per funzionare con numeri interi in cui l'overflow è identificato come un rischio. Tutti gli overflow vengono convertiti in eccezioni e gestiti. La classe è progettata per semplificare l'utilizzo corretto.
Ad esempio:
char CouldBlowUp(char a, char b, char c)
{
SafeInt<char> sa(a), sb(b), sc(c);
try
{
return (sa * sb + sc).Value();
}
catch(SafeIntException err)
{
ComplainLoudly(err.m_code);
}
return 0;
}
Anche Safeint viene utilizzato molto internamente in Microsoft in prodotti come Office.
Ref: testo del link
Non sono sicuro di aver capito esattamente la domanda, ma forse puoi fare qualcosa del tipo:
temp = value_to_be_added_to;
value_to_be_added_to += value_to_add;
if (temp > value_to_be_added_to)
{
overflow...
}
Poiché tornerà ai valori più bassi, puoi facilmente verificare se è traboccato.