Dato che .NET è più recente di C ++, qualcosa mi dice che potrebbero esserci problemi nell'uso di unsigned int anche per cose che "non possono" essere negative come un indice o una lunghezza di array.
Sì. Per alcuni tipi di applicazioni come l'elaborazione di immagini o l'elaborazione di array, è spesso necessario accedere agli elementi relativi alla posizione corrente:
sum = data[k - 2] + data[k - 1] + data[k] + data[k + 1] + ...
In questi tipi di applicazioni, non è possibile eseguire il controllo dell'intervallo con numeri interi senza segno senza pensare attentamente:
if (k - 2 < 0) {
throw std::out_of_range("will never be thrown");
}
if (k < 2) {
throw std::out_of_range("will be thrown");
}
if (k < 2uL) {
throw std::out_of_range("will be thrown, without signedness ambiguity");
}
Invece devi riorganizzare l'espressione di controllo della portata. Questa è la differenza principale. I programmatori devono anche ricordare le regole di conversione dei numeri interi. In caso di dubbi, rileggere http://en.cppreference.com/w/cpp/language/operator_arithmetic#Conversions
Molte applicazioni non devono utilizzare indici di array molto grandi, ma devono eseguire controlli di intervallo. Inoltre, molti programmatori non sono addestrati a fare questa ginnastica di riarrangiamento di espressione. Una singola occasione mancata apre le porte a un exploit.
C # è infatti progettato per quelle applicazioni che non avranno bisogno di più di 2 ^ 31 elementi per array. Ad esempio, un'applicazione per fogli di calcolo non ha bisogno di occuparsi di tante righe, colonne o celle. C # si occupa del limite superiore avendo un'aritmetica controllata opzionale che può essere abilitata per un blocco di codice con una parola chiave senza fare confusione con le opzioni del compilatore. Per questo motivo, C # favorisce l'uso di numeri interi con segno. Quando queste decisioni vengono considerate del tutto, ha senso.
Il C ++ è semplicemente diverso ed è più difficile ottenere il codice corretto.
Per quanto riguarda l'importanza pratica di consentire all'aritmetica firmata di rimuovere una potenziale violazione del "principio del minimo stupore", un caso emblematico è OpenCV, che utilizza numeri interi a 32 bit con segno per l'indice degli elementi della matrice, le dimensioni dell'array, il conteggio dei canali pixel, ecc. Immagine l'elaborazione è un esempio di dominio di programmazione che utilizza pesantemente l'indice di array relativo. Underflow intero senza segno (risultato negativo racchiuso) complicherà notevolmente l'implementazione dell'algoritmo.
-1
viene restituito da funzioni che restituiscono un indice, per indicare "non trovato" o "fuori portata". Viene inoltre restituito daCompare()
funzioni (implementazioneIComparable
). Un int a 32 bit è considerato il tipo da usare per un numero generale, per quello che spero siano ovvi motivi.