2009-09-11 12 views
18

Preferisci vedere qualcosa come t_byte* (con typedef unsigned char t_byte) o unsigned char* nel codice?Best practice: dovrei creare un typedef per byte in C o C++?

Sono inclinato verso lo t_byte nelle mie biblioteche, ma non ho mai lavorato a un grande progetto in cui è stato adottato questo approccio e mi sto chiedendo quali sono le insidie.

risposta

21

Se si utilizza C99 o più recente, è necessario utilizzare stdint.h per questo. uint8_t, in questo caso.

C++ non ha ottenuto questa intestazione fino a C++ 11, chiamandolo cstdint. Le vecchie versioni di Visual C++ non ti permettevano di usare il C99 stdint.h in codice C++, ma praticamente ogni altro compilatore C++ 98 lo faceva, quindi potresti avere quell'opzione anche quando usi vecchi compilatori.

Come con molte altre cose, Boost documenti su questa differenza in boost/integer.hpp, fornendo cose come uint8_t se la libreria C++ standard del compilatore non lo fa.

2

Personalmente preferisco boost::int8_t e boost::uint8_t.

Se non si desidera utilizzare Boost, è possibile prendere in prestito boost\cstdint.hpp.

Un'altra opzione è utilizzare portable version of stdint.h (collegamento dalla risposta this).

+9

Non sono davvero venduto per richiedere un'intestazione di boost solo per typedef. –

+0

Si noti che mentre stdint.h è definito da C99, non esiste lo standard richiesto dallo standard ISO C++ corrente (perché precede C99), quindi in alcuni compilatori è possibile utilizzare la convenzione C per i nomi di intestazione è utilizzare stdint tipi, e quella sarebbe la forma più portabile. – Clifford

1

Oltre alla tua convenzione di naming imbarazzante, penso che potrebbe andare bene. Tenete a mente spinta fa questo per voi, per aiutare con cross-platform-capacità:

#include <boost/integer.hpp> 

typedef boost::uint8_t byte_t; 

Si noti che di solito tipo di hanno come suffisso _t, come in byte_t.

+0

I tipi definiti NON devono essere contrassegnati con "_t" in quanto tali nomi sono riservati per le estensioni della lingua e delle librerie standard (ad esempio, l'aggiunta di uint8_t non interrompe molti codici esistenti). – Dipstick

+0

@chrisharris dove hai trovato queste informazioni? Sto osservando una bozza degli standard ISO C++ e non riesco a trovare quella sezione, ma ho un collega che a lui piace suffragare tutti i suoi modelli di classe/funzione in quel modo e vorrebbe indicarlo a lui. – stinky472

+0

@ stinky472: Non ho idea di cosa lo stia dicendo lo standard ISO C, ma il buon senso dice che i nomi personalizzati non devono scontrarsi con quelli standard, quindi per evitare problemi è meglio usare 'byte'. Oppure, se preferisce il tuo collega, usa un * prefisso * invece di un suffisso: 't_byte'. – MestreLion

7

suggerisco che se il vostro compilatore supporta utilizzare i tipi di intestazione C99<stdint.h> come uint8_t e int8_t.

Se il compilatore non lo supporta, crearne uno. Here's un esempio per VC++, le cui versioni precedenti non hanno stdint.h. GCC supporta stdint.h, e in effetti la maggior parte delle C99

Un problema con il tuo suggerimento è che il segno di char è implementazione definita, quindi se si fa creare un tipo alias. dovresti almeno essere esplicito riguardo al segno. C'è un merito nell'idea poiché in C# ad esempio uno char è 16 bit. Ma ha anche un tipo di byte.


Nota aggiuntiva ...

Non c'era alcun problema con il suggerimento, si fece infatti specificare non firmato.

Vorrei anche suggerire che il semplice char viene utilizzato se i dati sono in realtà dati di carattere, cioè una rappresentazione di testo normale come si potrebbe visualizzare su una console.Ciò presenterà un minor numero di problemi di tipo quando si utilizzano librerie standard e di terze parti. Se d'altro canto i dati rappresentano un'entità non carattere come una bitmap, o se si tratta di dati numerici di "intero piccolo" su cui è possibile eseguire la manipolazione aritmetica, o dati su cui si eseguiranno operazioni logiche, allora uno dei È necessario utilizzare i tipi stdint.h (o anche un tipo definito da uno di essi).

ho recentemente ha catturato su un TI C54xx compilatore dove char è infatti a 16 bit, in modo che è il motivo per cui utilizzando stdint.h ove possibile, anche se lo si utilizza per poi definire un tipo byte è preferibile supponendo che unsigned char sia un alias adatto.

+0

Buon punto sul mio esempio, ho contrassegnato la risposta di Warren corretta perché lui era il primo e il suo post era succinto. Hai svalutato almeno ... –

0

Preferisco utilizzare i tipi standard, char unsigned, uint8_t, ecc., Quindi qualsiasi programmatore che osserva la fonte non deve fare riferimento alle intestazioni per aggiungere il codice. Più tipodi usi più tempo ci vuole per far conoscere agli altri le tue convenzioni di digitazione. Per le strutture, usa assolutamente typedef, ma per le primitive usale con parsimonia.

4

Preferisco che i tipi trasmettano il significato dei valori memorizzati in esso. Se ho bisogno di un tipo che descrive un byte così com'è sulla mia macchina, preferisco decisamente lo byte_t su unsigned char, il che potrebbe significare qualsiasi cosa. (Ho lavorato su un codice base che utilizzava signed char o unsigned char per memorizzare stringhe UTF-8.) Lo stesso vale per uint8_t. Potrebbe essere usato solo così: un intero senza segno a 8 bit.

Con byte_t (come con qualsiasi altro tipo con nome appropriato), raramente è necessario cercare in che modo viene definito (e in tal caso, un buon editor richiederà 3 secondi per cercarlo, forse 10 secondi , se il codice base è enorme), e solo guardandolo è chiaro cosa è memorizzato in oggetti di quel tipo.

Problemi correlati