Cosa posso assumere in merito al comportamento di atoi () in caso di errore?

La funzione di libreria C standard atoi è documentata in ISO 9899: 2011 come:

7.22.1 Funzioni di conversione numerica

1 Le funzioni atof , atoi , atol e atoll non hanno bisogno di influenzare il valore dell’espressione intera errno un errore. Se il valore del risultato non può essere rappresentato, il comportamento non è definito.

7.22.1.2 Le atoi , atol e atoll

Sinossi

 #include  int atoi(const char *nptr); long int atol(const char *nptr); long long int atoll(const char *nptr); 

Descrizione

2 Le atoi , atol e atoll convertono la parte iniziale della stringa puntata da nptr in int , long int e long long int , rispettivamente. Ad eccezione del comportamento sull’errore, sono equivalenti a

 atoi: (int)strtol(nptr, (char **)NULL, 10) atol: strtol(nptr, (char **)NULL, 10) atoll: strtoll(nptr, (char **)NULL, 10) 

ritorna

3 Le atoi , atol e atoll restituiscono il valore convertito.

Qual è il comportamento previsto quando la stringa a cui punta nptr non può essere analizzata come un intero? Le seguenti quattro opinioni sembrano esistere:

  • Nessuna conversione viene eseguita e zero viene restituito. Questa è la documentazione fornita da alcuni riferimenti come questo .
  • Il comportamento è simile a quello di strtol tranne che errno potrebbe non essere impostato. Questo emerge dal prendere “Tranne il comportamento in caso di errore” come riferimento a §7.22.1 ¶1.
  • Il comportamento non è specificato. Questo è ciò che dice POSIX :

    La call atoi (str) deve essere equivalente a:

     (int) strtol(str, (char **)NULL, 10) 

    salvo che la gestione degli errori può essere diversa. Se il valore non può essere rappresentato, il comportamento non è definito.

    Inoltre, la sezione Uso dell’applicazione afferma:

    La funzione atoi () è sussunta da strtol () ma viene mantenuta perché è ampiamente utilizzata nel codice esistente. Se il numero non è compreso nell’intervallo, è necessario utilizzare strtol () perché atoi () non è richiesto per eseguire un controllo degli errori.

    Si noti che POSIX afferma che la specifica è allineata a ISO 9899: 1999 (che contiene la stessa lingua di ISO 9899: 2011 per quanto mi riguarda):

    La funzionalità descritta in questa pagina di riferimento è allineata con lo standard ISO C. Qualsiasi conflitto tra i requisiti descritti qui e lo standard ISO C non è intenzionale. Questo volume di POSIX.1-2008 definisce lo standard ISO C.

    Secondo il mio membro del comitato POSIX locale, questo è il comportamento storico di UNIX.

  • Il comportamento non è definito. Questa interpretazione deriva dal fatto che §7.22.1.2 ¶2 non dice mai esplicitamente cosa succede in caso di errore. Il comportamento che non è né definito né esplicitamente implementato definito o non specificato non è definito.

Quale di queste interpretazioni è corretta? Si prega di provare a fare riferimento alla documentazione autorevole.

Qual è il comportamento previsto quando la stringa a cui punta nptr non può essere analizzata come un intero?

Per essere chiari, questa domanda si applica a

 // Case 1 value = atoi(""); value = atoi(" "); value = atoi("wxyz"); 

e non il seguente:

 // Case 2 // NULL does not point to a string value = atoi(NULL); // Convert the initial portion, yet has following junk value = atoi("123xyz"); value = atoi("123 "); 

E forse / forse non il seguente a seconda dell’uso del numero intero .

 // Case 3 // Can be parsed as an _integer_, yet overflows an `int`. value = atoi("12345678901234567890123456789012345678901234567890"); 

Il comportamento “non-caso 2” di ato*() dipende dal significato dell’errore in

Le atoi , atol e atoll convertono la parte iniziale della stringa puntata da nptr in int , long int e long long int , rispettivamente. Ad eccezione del comportamento sull’errore , sono equivalenti a
atoi: (int)strtol(nptr, (char **)NULL, 10)
...
C11dr §7.22.1.2 2


Certamente l’ errore include il caso 3: “Se il valore corretto è al di fuori dell’intervallo di valori rappresentabili”. strto*() , anche se forse non ato*() , in questo caso imposta il numero errore errrno definito in . Poiché la specifica di ato*() non si applica a questo errore , l’overflow, il risultato, è UB per

Il comportamento indefinito è altrimenti indicato in questo standard internazionale dalle parole “comportamento indefinito” o dall’omissione di qualsiasi definizione esplicita di comportamento. C11dr §4 2


Per il caso 1, il comportamento di strto*() è ben definito e non viene specificato per influenzare errno . La specifica va in dettaglio (§7.22.1.4 4) e chiama questi “nessuna conversione”, non un errore . Quindi può affermare che il caso 1 strto*() non è un errore , ma una “nessuna conversione”. Quindi per …

“Se non è ansible eseguire alcuna conversione, viene restituito zero C11dr §7.22.1.4 8

atoi("") deve restituire 0.