Domanda

In diversi esempi di C ++ vedo un uso del tipo size_t dove avrei usato un semplice int. Qual è la differenza e perché size_t dovrebbe essere migliore?

È stato utile?

Soluzione

Da l'amichevole Wikipedia :

  

I file di intestazione stdlib.h e stddef.h definiscono un tipo di dati chiamato size_t che viene utilizzato per rappresentare la dimensione di un oggetto. Le funzioni di libreria che accettano dimensioni si aspettano che siano di tipo size_t e l'operatore sizeof restituisce size_t.

     

Il tipo effettivo di size_t dipende dalla piattaforma; un errore comune è supporre che size_t sia uguale a unsigned int, il che può portare a errori di programmazione, in particolare quando le architetture a 64 bit diventano più prevalenti.

Inoltre, controlla Perché size_t importa

Altri suggerimenti

size_t è il tipo utilizzato per rappresentare le dimensioni (come suggerisce il nome). La sua piattaforma (e anche potenzialmente l'implementazione) dipende e dovrebbe essere utilizzata solo per questo scopo. Ovviamente, rappresentando una dimensione, size_t non è firmato. Molte funzioni stdlib, tra cui malloc, sizeof e varie funzioni operative delle stringhe utilizzano size_t come tipo di dati.

Un int è firmato per impostazione predefinita e anche se le sue dimensioni dipendono anche dalla piattaforma, saranno 32 bit fissi sulla maggior parte delle macchine moderne (e sebbene size_t sia 64 bit su un'architettura a 64 bit, int rimarrà a 32 bit su quelle architetture ).

Per riassumere: usa size_t per rappresentare la dimensione di un oggetto e int (o long) negli altri casi.

È perché size_t può essere qualcosa di diverso da un int (forse uno struct). L'idea è che disaccoppia il suo lavoro dal tipo sottostante.

Il tipo size_t è definito come il tipo integrale senza segno dell'operatore sizeof. Nel mondo reale, vedrai spesso int definiti come 32 bit (per compatibilità con le versioni precedenti) ma long int definiti come 64 bit (quindi puoi dichiarare matrici e strutture di dimensioni superiori a 4 GiB) su piattaforme a 64 bit. Se anche long long int è a 64 bit, questa si chiama convenzione LP64; se unsigned int è 32 bit ma 1U < -3 e i puntatori sono 64 bit, allora & # 8217; s LLP64. Potresti anche ottenere il contrario, un programma che utilizza istruzioni a 64 bit per la velocità, ma puntatori a 32 bit per risparmiare memoria. Inoltre, ptrdiff_t è firmato e <stddef.h> non è firmato.

Storicamente c'erano diverse altre piattaforme in cui gli indirizzi erano più larghi o più corti della dimensione nativa di INT_MAX. In effetti, negli & # 8217; anni '70 e primi & # 8217; anni '80, questo era più comune che no: tutti i popolari microcomputer a 8 bit avevano registri a 8 bit e indirizzi a 16 bit e la transizione tra 16 e 32 bit producevano anche molte macchine che avevano indirizzi più ampi dei loro registri. Di tanto in tanto vedo ancora domande su Borland Turbo C per MS-DOS, la cui modalità di memoria enorme aveva indirizzi a 20 bit memorizzati in 32 bit su una CPU a 16 bit (ma che poteva supportare il set di istruzioni a 32 bit dell'80386); il Motorola 68000 aveva un ALU a 16 bit con registri e indirizzi a 32 bit; c'erano mainframe IBM con indirizzi a 15, 24 o 31 bit. Si vedono anche diverse ALU e dimensioni del bus dell'indirizzo nei sistemi integrati.

Ogni volta che 0 è inferiore a INT_MIN e si tenta di memorizzare la dimensione o l'offset di un file o oggetto molto grande in un <=>, esiste la possibilità che possa traboccare e causare un bug. Con un <=>, c'è anche la possibilità di ottenere un numero negativo. Se un <=> o <=> è più ampio, il programma verrà eseguito correttamente ma sprecherà memoria.

In genere si dovrebbe usare il tipo corretto per lo scopo se si desidera la portabilità. Molte persone raccomandano di usare la matematica firmata anziché quella non firmata (per evitare bug cattivi e sottili come <=>). A tale scopo, la libreria standard definisce <=> in <=> come il tipo firmato del risultato della sottrazione di un puntatore da un altro.

Detto questo, una soluzione alternativa potrebbe essere quella di controllare i limiti di tutti gli indirizzi e gli offset rispetto a <=> e <=> o <=>, a seconda dei casi, e attivare gli avvisi del compilatore sul confronto tra quantità firmate e non firmate in caso di perdita qualunque. Dovresti sempre, sempre, controllare sempre gli accessi al tuo array per overflow in C. comunque.

La definizione di SIZE_T si trova in: https://msdn.microsoft.com/en-us/library/cc441980. aspx e https://msdn.microsoft.com/en- us / library / cc230394.aspx

Incollando qui le informazioni richieste:

ULONG_PTR è un <=> che rappresenta il numero massimo di byte a cui può puntare un puntatore.

Questo tipo è dichiarato come segue:

typedef ULONG_PTR SIZE_T;

Un <=> è un tipo lungo senza segno utilizzato per la precisione del puntatore. Viene usato quando si lancia un puntatore su un tipo lungo per eseguire l'aritmetica del puntatore.

Questo tipo è dichiarato come segue:

typedef unsigned __int3264 ULONG_PTR;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top