I am in the process of porting a C++ application to x64 from x86. Now, there is a custom array class with functions like GetRowCount(); etc. If these functions return a size_t (and the whole array class would be dealing with size_t for indexing) it would mean I could get (2^64)-1 items in such an array, but if I would utilize a signed ptrdiff_t instead I would lose much of the max array size. My question is basically which types to use: signed or unsigned types for arrays? I have been reading other topics on this but they have been purely focused on indexing.

The problem I see is due to let's say somewhere code looks something like this:

[signed/unsigned type] result = customArray.GetRowCount() - a;

where in some cases the variable "a" may be signed and in other cases unsigned, and assuming it could be larger than the row count returned. What is then done with the "result" variable I don't know, but it could for instance be used in some further arithmetic operations.

So, to stay out of trouble with mixing signed and unsigned arithmetic and implicit casts in code which utilizes the custom array class, should I in that array class instead be working with ptrdiff_t and thereby also let functions like GetRowCount() return a ptrdiff_t? Or should I use intptr_t, is it more logical?

Here http://www.viva64.com/en/a/0050/ the example shows ptrdiff_t should be used...

However, like stated in the beginning I can then no longer index arrays with up to SIZE_MAX elements since half of the value span of a signed type will be used for negative values.

I hope I am making any sense and would really appreciate some clarification and guidance. Thank you all in advance!


답변

This is pretty close to a matter of personal taste.

Some people say any use of an unsigned integral type for anything other than bit manipulation is faulty, and use signed types for all quantities. Others (including the designers of the C++ standard libraries) use unsigned types for counting things. Neither side of the debate has ever proven that the other side are total idiots who can't write decent code (although I think occasional individuals on both sides have claimed they have).

I feel that unless you're going to eliminate unsigned types entirely you might as well copy the standard. If the array is backed by memory then it's unlikely that an implementation will create an array half the size of the address space even on a 32 bit system. On a 64 bit system it's utterly infeasible. If you arrange for your array class to prevent that it's not much of a loss. So the max value of the type isn't really a concern.

However, that's for newly-designed code. If the class is central then you shouldn't change its interface more than necessary. Either continue with int or switch to ptrdiff_t if you need more capacity. Definitely don't use intptr_t. That's for storing addresses, not counts or offsets.



이런 의견도 있네

취향이래 ,,,, 흠.,,