2016-08-24 24 views
6

wiem, że średnia C pozwala na implementacje gdzierzeczywistym realizacja gdzie sizeof (size_t) <sizeof (unsigned int)

(sizeof(unsigned) > sizeof(size_t)) 

lub

(sizeof(int) > sizeof(ptrdiff_t)) 

jest prawdą. Ale czy są jakieś prawdziwe implementacje, w których jedna z nich jest prawdziwa?

Tło

napisałem funkcję podobną do asprintf() (od asprintf() nie jest przenośny), a snprintf() zwrócić int ale potrzebuje size_t argumentu, więc należy sprawdzić, czy leni (poniżej) jest nie mniejsza niż SIZE_MAX w tym kodzie?

va_copy(atmp,args) 
int leni = vsnprintf(NULL,0,format,atmp); //get the size of the new string 
va_end(atmp); 
if(leni<0) 
    //do some error handling 
if(leni>=SIZE_MAX) //do i need this part? 
    //error handling 
size_t lens = ((size_t)leni)+1; 
char *newString = malloc(lens); 
if(!newString) 
    //do some error hanling 
vsnprintf(newString,lens,format,args)!=lens-1) 
+0

Nie jestem pewien, czy to rzeczywiście możliwe, w przeciwnym razie 'sizeof (char [LARGE_NUMBER])' nie zawsze będzie działać. –

+0

@OliverCharlesworth Nie zawsze działa, jeśli napiszesz coś w stylu char str [1024ULL * 1024ULL * 1024ULL * 5]; otrzymasz błąd kompilacji na komputerach 32-bitowych (przynajmniej w moim przypadku z gcc -m32) (ale nie na AMD64) – 12431234123412341234123

+0

@OliverCharlesworth To nie musi. Jeśli wyrażenie stałe w nawiasach tworzy obiekt, który nie może być reprezentowany przez size_t, który będzie wynikiem sizeof, wówczas kompilator wygeneruje błąd. – 2501

Odpowiedz

3

Podczas gdy średnia nie zabrania że INT_MAX nie będzie mniejsza niż SIZE_MAX The vsnprintf funkcja gwarantuje, że zwrócona wartość nie będzie większa niż SIZE_MAX.

Jeśli funkcje powiedzie się, to wartość zwracana musi być mniejsza niż jej drugi argument . Ten argument ma typ size_t, dlatego zwracana wartość musi być mniejsza niż SIZE_MAX. .

A jeśli nie jesteś przekonany, zawsze możesz użyć dyrektywy preprocesora, która ocenia INT_MAX> SIZE_MAX, a następnie dołączyć potrzebny kod, który sprawdza wynik vsnprintf.


Identyfikator n wspomniane w standardowych Odniesienie poniżej, to drugi argument vsnprintf.

(Cytat z: ISO/IEC 9899: 201x 7.21.6.12 Funkcja vsnprintf 3)
Funkcja vsnprintf zwraca liczbę znaków, które zostały napisane miał n dostatecznie duża, nie licząc kończące znak null lub wartość ujemną, jeśli wystąpił błąd kodowania. Tak więc, zakończone znakiem NUL wyjście zostało całkowicie zapisane wtedy i tylko wtedy, gdy zwrócona wartość jest nieujemna i mniejsza niż n.

+0

Przepraszam, jeśli nie rozumiem cię w 100%. Ale jeśli ustawisz n na 0, (co robię) zwrócona liczba nie może być równa lub mniejsza niż n, więc czy nie może być tak, że zwrócona wartość jest większa niż SIZE_MAX? – 12431234123412341234123

+0

@ 12431234123412341234123 Standard oznacza, że ​​zwracana wartość nie może być większa niż n, z limitem SIZE_MAX. Jeśli uważasz, że orzeczenie jest zbyt ogólnikowe, aby być wiarygodnym, wystarczy dodać czek zabezpieczony przez dyrektywy preprocesora i zapomnieć o tym. – 2501