Can sizeof(size_t)
be less than sizeof(int)
?
Do the C and/or C++ standards guarantee that using unsigned int
for array indexing is always safe?
Can sizeof(size_t)
be less than sizeof(int)
?
Do the C and/or C++ standards guarantee that using unsigned int
for array indexing is always safe?
Yes, sizeof(size_t)
can, in principle, be less than sizeof(int)
. I don't know of any implementations where this is true, and it's likely that there are none. I can imagine an implementation with 64-bit int
and 32-bit size_t
.
But indexing an array with unsigned int
is safe -- as long as the value of the index is within the bounds imposed by the length of the array. The argument to the []
operator is merely required to be an integer. It's not converted to size_t
. It's defined in terms of pointer arithmetic, in which the +
operator has one argument that's a pointer and another argument that is of any integer type.
If unsigned int
is wider than size_t
, then an unsigned int
index value that exceeds SIZE_MAX
will almost certainly cause problems because the array isn't that big. In C++14 and later, defining a type bigger than SIZE_MAX
bytes is explicitly prohibited (3.9.2 [compound.types] paragraph 2; section 6.9.2 in C++17). In earlier versions of C++, and in all versions of C, it isn't explicitly prohibited, but it's unlikely that any sane implementation would allow it.
size_t
, so that the original question is meaningful, an index of type size_t
can express at least one value that is out of bounds for every array. For substantially all arrays actually observed in real programs, a size_t
can express very many out of bounds indexes. Its association with the maximum possible size of objects, where that exists, does not make it safer for indexing. –
Margetmargette SIZE_MAX
or less. I suspect this in a C++ thing. –
Derbyshire SIZE_MAX
. C has no explicit requirement that objects can't be bigger than SIZE_MAX
bytes. A C implementation could, for example, have 32-bit size_t
but allow 2<sup>33</sup>-element arrays -- then sizeof obj
could overflow. The obvious solution would be for such an implementation to make its size_t
big enough to hold the size of any object. Apparently this doesn't apply to C++14 and later. –
Faline sizeof
operator yields the size (in bytes) of its operand" can also be read as "C has no explicit requirement that objects can be bigger than SIZE_MAX
. I'll grant that this is not explicit either way about can/can't be bigger... But the implication, IMO is cannot. Looks like a good SO question unto itself. –
Derbyshire size_t
that allows 2**33-element arrays would violate any requirement in the C (or C++ prior to 2014) standard. Possibly it's a case the authors didn't think of. IMHO sizeof ...
can overflow just like any other arithmetic expression. –
Faline std::size_t
is ill-formed." (3.9.2 [basic.compound] paragraph 3). This wording is not in C++11 (or in any edition of ISO C). –
Faline [C answer]
Can
sizeof(size_t)
be less thansizeof(int)
?
Yes. The size of size_t
can be less, more or the same as int
as their relative sizes/ranges are not specified in C - only their minimum _MAX
values: 65535, 32767.
IMO, sizeof(size_t) < sizeof(int)
is a unicorn. Theoretical, but not seen.
Code could use the following to detect such beasties.
#include <limits.h>
#include <stddef.h>
#if SIZE_MAX < UINT_MAX
#error Unexpected small size_t
#endif
Do the C and/or C++ standards guarantee that using
unsigned int
for array indexing is always safe?
In C, No.
Examples: A small array may only tolerate the indexes of [0 ... 2] - regardless of the type of the index - not the entire range of unsigned
. A huge array may be index-able [0 ... UINT_MAX*42ull
] and so an unsigned
cannot represent all valid indexes.
A size_t
is wide enough to index all arrays.
© 2022 - 2024 — McMap. All rights reserved.
unsigned int
be safe? Array indexes can't be negative. Are you ever planning on having so many array elements as to overflow anunsigned int
? It is technically possible forsizeof(size_t)
to be more thansizeof(int)
(ie, ifsize_t
isunsigned long long
on a 64bit system), but I doubt you will ever see it be less. – Nethermostint
. Maybe NoSkill is confused similarly? – Ezzoint
– Nethermostunsigned int
might be too large. e.g.size_t == unsigned char
– Zoezoellerint arr[10]; int *ptr = arr+5; ptr[-5] = 0;
is perfectly valid. – FalineUnsigned integer type of the result of the sizeof operator
. – Ezzoarr[0]
using pointer arithmetic.arr[-1]
is not valid, for instance. Neither wouldptr[-6]
in your example. – Nethermost[]
operator is defined in terms of pointer arithmetic. The pointer is required to point to an element of an array object (including a non-array object that's treated as a 1-element array). If by "array index" you mean the index relative to the base of the array object into which the pointer points, then you're right, but the standard doesn't describe it in those terms. – Falinearray::operator[](int)
notarray::operator[](unsigned)
– Uncommunicative