Is it safe to transfer numbering based on 1 to numbering by 0, subtracting 1 if unsigned integers are used?

On the system that I support, users request items from the collection from a 1-based indexing scheme. Values ​​are stored in 0-based arrays in C ++ / C.

Is the following hypothetical code portable if 0 was mistakenly entered as an input to this function? Is there a better way to check user input when converting numbering schemes based on 1 to 0?

const unsigned int arraySize; SomeType array[arraySize]; SomeType GetFromArray( unsigned int oneBasedIndex ) { unsigned int zeroBasedIndex = oneBasedIndex - 1; //Intent is to check for a valid index. if( zeroBasedIndex < arraySize ) { return array[zeroBasedIndex]; } //else... handle the error } 

My assumption is that (unsigned int)( 0 - 1 ) always larger than arraySize ; it's true?

An alternative, as some of them suggested in their answers below, is to check oneBasedIndex and make sure that it is greater than 0:

 const unsigned int arraySize; SomeType array[arraySize]; SomeType GetFromArray( unsigned int oneBasedIndex ) { if( oneBasedIndex > 0 && oneBasedIndex <= arraySize ) { return array[oneBasedIndex - 1]; } //else... handle the error } 
+4
source share
5 answers

For unsigned types, 0-1 is the maximum value for this type, so it is always >= arraySize . In other words, yes, it is absolutely safe.

+5
source

Unsigned integers never overflow in C ++ and C.

For C ++:

(C ++ 11, 3.9.1p4) "Unsigned unsigned integers must obey the laws of arithmetic modulo 2n, where n is the number of bits in the representation of the values ​​of this particular integer size. 46)"

and footnote 46):

"46) This means that unsigned arithmetic is not overflowing, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo to a number that is greater than one largest value that can be represented by the resulting unsigned integer."

and for the C language:

(C11, 6.2.5p9) "Computing using unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is equal in magnitude to a number that is greater than one largest value that can be represented by the resulting type. "

+5
source

This is most likely safe, but for many purposes there is a much simpler way: allocate another space in your array and simply ignore element 0.

+4
source

No, for example, 0-1 is 0xffffffff in a 4-byte unsigned int, what if your array is really so big? 32 bits are fine, because 0xffffffff exceeds the limit, the code breaks when compiling to 64 bits if the array is so large.

Just check for oneBasedIndex> 0

+1
source

Make sure oneBasedIndex greater than zero ...

0
source

Source: https://habr.com/ru/post/1403753/


All Articles