Perché utilizziamo tipi specifici dell'architettura in C

3

Penso che i nomi dei tipi in Rust siano molto migliori di quelli in C. Io sceglierei f64 su double e u32 su unsigned int o uint_32t ogni giorno. C'è qualche ragione (diversa dalla tradizione) per usare quei nomi intuitivi e difficili da imparare?

So che nomi come short e long sono specifici dell'architettura, ma ciò non rende il problema reale ancora peggiore? Si dice che C sia un "assembly portatile", ma nel linguaggio assembly bisogna effettivamente usare registri e dimensioni corretti, che sono definiti dall'architettura, proprio come in C . Pertanto non sono sicuro di come questo in realtà ci aiuti a produrre codice migliore (in termini di leggibilità).

L'unico problema che posso pensare riguarda la dimensione dei byte. Se il byte non è otto bit, usare i numeri di bit nei nomi dei tipi non sarebbe così intelligente. Ma allora, perché non usiamo alcuni nomi chiari che ci dicono multipli esatti di byte che il tipo di dati contiene, come sb (singolo byte), db (doppio byte), qb (quad byte)?

Quindi, perché utilizziamo nomi di tipi specifici dell'architettura in C , anche quando non è necessario?

    
posta Hannes Karppila 11.06.2016 - 23:21
fonte

1 risposta

6

Poiché il linguaggio C è progettato per essere implementato su qualsiasi piattaforma, indipendentemente dal numero di dimensioni integer fornite in modo nativo.

Infatti, nessuno dei tipi intN_t è garantito per esistere affatto . Solo un'implementazione che fornisce un intero con segno a complemento a due di esattamente N bit (nessun bit di riempimento consentito) definirà il corrispondente tipo intN_t (vedere la sezione 7.20.1.1 dello standard C11).

I tipi char, int, long , etc sono tutti garantiti per esistere, e sono garantiti per consentire determinati intervalli di valori (vedere la sezione 5.2.4.2.1 dello standard C11), ma potrebbero non essere il complemento a due, potrebbero consente più valori oltre all'intervallo richiesto, potrebbero essere tutti dello stesso tipo nell'implementazione sottostante e potrebbero anche essere implementati nel software anziché nell'hardware. In altre parole, i tipi C normali "normali" non garantiscono assolutamente nulla tranne un intervallo di valori che possono essere assegnati. Questo è ciò che li rende estremamente portabili.

Ovviamente, in pratica, il motivo principale per cui stiamo ancora usando char, int, long , ecc. è perché è tutto ciò che C ha da molto tempo, questo è ciò che tutti sono abituati a usare, e le differenze tecniche tra char, int8_t, uint8_t, int_least8_t, int_fast8_t e così via semplicemente non importa una grande quantità di codice.

Ma se ti preoccupi di ottenere i tipi ottimali, o sei su uno dei progetti in cui queste distinzioni sono importanti, allora vale la pena sottolineare che i tipi int_leastN_t e int_fastN_t sono garantiti per esistere su tutte le implementazioni conformi (vedere le sezioni 7.20.1.2 e 7.20.1.3 dello standard C11), il che significa che hanno un enorme vantaggio di portabilità rispetto ai tipi intN_t .

Come per Rust, ciò che sono riuscito a raccogliere dalla loro documentazione è questo: i tipi interi di Rust devono esistere in tutte le implementazioni Rust conformi, quelli firmati sono necessari per usare il complemento a due, devono avere un comportamento di overflow definito, e non riesco a trovare alcuna prova di un requisito "no padding bit". In altre parole, i tipi di Rust integer non sono nemmeno vicini a una corrispondenza perfetta per nessuno dei tipi di C11 interi.

    
risposta data 12.06.2016 - 01:13
fonte

Leggi altre domande sui tag