Perché non erano nuove (larghezza specifici bit) printf () in formato stringhe di opzione ADOTTATA come parte di C99?
-
19-09-2019 - |
Domanda
Mentre la ricerca di come fare cross-platform stringhe di formato printf()
in C (vale a dire, prendendo in considerazione il numero di bit mi aspetto che ogni argomento un intero ad printf()
dovrebbe essere) mi sono imbattuto in questa sezione alle voci di Wikipedia printf()
. L'articolo discute opzioni non standard che possono essere passati al printf()
stringhe di formato, come ad esempio (quello che sembra essere un estensione di Microsoft-specifico):
printf("%I32d\n", my32bitInt);
Si prosegue affermando che:
ISO C99 include l'intestazione inttypes.h file che include un certo numero di macro per l'uso in printf indipendente dalla piattaforma codifica.
... e poi elenca una serie di macro che si possono trovare in tale intestazione. Guardando il file di intestazione, per usarli avrei dovuto scrivere:
printf("%"PRId32"\n", my32bitInt);
La mia domanda è: mi sto perdendo qualcosa? E 'davvero questo il modo standard C99 per farlo? Se sì, perché? (Anche se io non sono sorpreso che non ho mai visto il codice che utilizza le stringhe di formato in questo modo, dal momento che sembra così ingombrante ...)
Soluzione
La logica C sembra implicare che la pratica
è stato derivato dal collettore omonimo trovato su diversi sistemi a 64 bit esistenti.
, ma il resto del testo non scrive su quelle macro, e non ricordo che stavano per rispettare gli usi al momento.
Quello che segue è solo speculazione, ma educato da esperienza di come i comitati di standardizzazione funzionano.
Un vantaggio delle macro C99 oltre standardizzazione ulteriore identificatore di formato per printf (si noti che C99 ha fatto anche aggiungere un po ') è che fornire <inttypes.h>
e <stdint.h>
quando si dispone già di un'implementazione supportare le caratteristiche richieste in maniera specifica implementazione è solo scrivendo due file con adeguata typedef e macro. Che riduce il costo di fabbricazione conforme implementazione esistente, riduce il rischio di rottura programmi esistenti che hanno fatto uso delle caratteristiche specifiche di implementazione esistenti (il modo standard non interferisce) e facilitare il porting di programmi Conformant di attuazione che non hanno questi intestazioni (che possono essere forniti dal programma). Inoltre, se le modalità di implementazione specifica già variato, al momento, non favorize un'implementazione rispetto ad un altro.
Altri suggerimenti
corretta, questo è il modo lo standard C99 dice di loro si dovrebbe usare. Se si desidera che il codice veramente portablt che è% 100 su standard conforme alla lettera, si dovrebbe sempre stampare un int
utilizzando "%d"
ed un int32_t
utilizzando "%"PRId32
.
La maggior parte delle persone non preoccupatevi, però, dato che ci sono pochissimi casi in cui in caso contrario si avrebbe importanza. A meno che non si sta porting il codice per Win16 o DOS, si può supporre che sizeof(int32_t) <= sizeof(int)
, quindi è innocuo per printf accidentalmente un int32_t
come int
. Allo stesso modo, un long long
è praticamente universale 64 bit (anche se non è garantito essere così), quindi la stampa di un int64_t
come long long
(ad esempio con una specifica %llx
) è sicuro pure.
Il tipo int_fast32_t
, int_least32_t
, et al vengono quasi mai utilizzati, in modo da poter immaginare che i loro identificatori di formato corrispondenti vengono utilizzati sempre più raramente.
È sempre possibile lanciare verso l'alto e utilizzare %jd
che è l'identificatore di formato intmax_t
.
printf("%jd\n", (intmax_t)(-2));
Ho usato intmax_t
di dimostrare che qualsiasi intXX_t
può essere utilizzato, ma la fusione per long
semplicemente è molto meglio per il caso int32_t
, quindi utilizzare %ld
.
Posso solo speculare sul perché. Mi piace la risposta di AProgrammer sopra, ma c'è un aspetto trascurato:? che cosa hai intenzione di aggiungere printf come modificatore formato Ci sono già due modi diversi che i numeri sono utilizzati in una stringa di formato printf (larghezza e precisione). L'aggiunta di un terzo tipo di numero per dire quanti bit di precisione sono l'argomento sarebbe grande, ma dove stai andando a metterlo senza confondere la gente? Unfortunatey uno dei difetti in C è che printf non è stato progettato per essere estensibile.
Le macro sono terribili, ma quando si deve scrivere il codice che è portabile su piattaforme a 32 bit e 64 bit, sono una manna dal cielo. Sicuramente salvato la mia pancetta.
Penso che la risposta alla tua domanda perché è
- Nessuno poteva pensare ad un modo migliore per farlo, o
- Il comitato standard non poteva d'accordo su nulla si sono sentiti è stato nettamente migliore.
Un'altra possibilità: compatibilità. Se si aggiungono altri identificatori di formato per printf
, o alle opzioni aggiuntive, è possibile che un identificatore di qualche codice pre-C99 avrebbe una stringa di formato interpretata in modo diverso.
Con il cambiamento C99, non stai cambiando la funzionalità di printf
.