4

What is the natural parameter type for the operator [] on pointers, as in:

struct foo
{
  value_t operator[](<TYPE?> i)
    { return data[i]; }

  value_t * data;
};

I know that I can feed in any integer type, but what is the natural type for array indexing, ie. the one which does not cause implicit conversion?

9
  • 6
    size_t is a natural choice Commented Feb 28, 2013 at 21:20
  • Is that really what the compiler uses? size_t is unsigned, but I am certainly allowed to use negative indices in C++ indexing. Commented Feb 28, 2013 at 21:22
  • The compiler uses what, where? Define what you mean by natural. If your container doesn't support negative indexing, than it's natural to accept only an unsigned index. Commented Feb 28, 2013 at 21:25
  • By "natural" I mean "a compiler does not perform implicit conversion". If there is a standardized data type for that, what is it? And if it's not standardized (like some compilers accept negative indices, others not, or compilers use different data types internally), then I'm also grateful for authoritative information on that. Commented Feb 28, 2013 at 21:27
  • mmm... I don't think the standard specifies a specific integral data type. But if I had to venture a guess, I'd say it's a type which holds sizeof(integral_type) == sizeof (pointer). So long, probably. Commented Feb 28, 2013 at 21:32

1 Answer 1

5

operator [] on pointers can be any integral expression

To be general, ptrdiff_t is technically what you want, if the intention is for data and data + i to be any two arbitrary pointers in either other and to arbitrary blocks of memory, since ptrdiff_t is defined as a signed type for holding the difference between two pointers (however, it's not guaranteed to not overflow: ptrdiff_t on machines with 32-bit pointers is typically 32-bit, not the next signed integral size higher)

In std::vector<T>, size_t is (typically) used, because std::vector has the additional restriction that the pointer points to the beginning of a block and indexing is only allowed within the allocated block, which cannot be larger than size_t by definition, and no negative indicies are allowed. size_t can be smaller than ptrdiff_t or uintptr_t (the unsigned integral type that can hold a pointer), for example on segmented architectures in which memory allocations are limited to one segment but pointers are not.

Now, if the intention is that data and data + i are part of the same block of memory but not necessarily such that data + i >= data, then I don't think there's an exact fit natural data type (i.e. a signed counterpart to size_t...I could be wrong) in Standard C++ (ssize_t is a POSIX extension), but you can go with ptrdiff_t since it's guaranteed to be at least as large as what you want.

There's no guarantee that sizeof(long) or sizeof(int) have any relationship with sizeof(ptrdiff_t) or sizeof(size_t)...assuming so can lead to nasty bugs.

EDIT: Technically, there's no portable way to obtain data and i such that data and data + i are both valid pointers and point to different objects in different allocation blocks, since the standard only guarantees that pointer arithmetic is well-defined within an allocated block, so if you're relying on doing so then your program is non-portable anyway. (Not that it won't work, in most cases...)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.