The C++ standard mentions this for std::size_t
:
The type
size_t
is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object ([expr.sizeof]).
Now my question is that if this type is a distinct type from other unsigned int types or not. I mean, should I be able to have overloads like this or not:
void myfunc(std::uint16_t) {}
void myfunc(std::uint32_t) {}
void myfunc(std::uint64_t) {}
void myfunc(std::size_t) {}
Because if it is a distinct type, I should be able to have these overloads while if it is not, I should get redefinition error. I somehow always thought that std::size_t
should be a distinct type but I currently get redefinition error which means it is not (at least in GCC and Clang)
The reason that I'm asking this is that I want to know if I have overload of a function for different unsigned int sizes, can I safely assume that one of them will be called for std::size_t
or not.
Now my question is that if this type is a distinct type from other unsigned int types or not.
Your question heavily depends on what exactly you mean with "unsigned int types". I'll assume this to refer to "unsigned integer types" as defined by the standard.
It can not be a type distinct from other unsigned integer types. All unsigned integer types are listed exclusively in [basic.fundamental]/2. These are the standard unsigned integer types unsigned char
, unsigned short
, unsigned int
, unsigned long
and unsigned long long
, and extended unsigned integer types if the implementation defines any (which isn't usually the case in the most common C++ implementations).
If you intend "unsigned int types" to refer to the standard unsigned integer types listed above, then the answer becomes that size_t
is neither required, nor prohibited, to be one of them, since it may also be one of the extended unsigned integer types. But if the implementation has none of those, then it must be one of the standard unsigned integer types.
If you intend "unsigned int types" to mean any "integer types" as defined in the standard which also have unsigned signdness, then the answer is again that it cannot be distinct from this set, since this set merely is a superset of the set of all unsigned integer types, adding char8_t
, char16_t
, char32_t
and potentially char
and wchar_t
(which have implementation-defined signdness).
(You can find definitions for all the mentioned terms from the standard in [basic.fundamental]/1 to 11 of the post-C++20 ISO C++ draft N4868 I linked above.)
Because if it is a distinct type, I should be able to have these overloads while if it is not, I should get redefinition error.
Regardless of the above, it is not guaranteed to cause a redefinition error, because while the types uint16_t
, uint32_t
and uint64_t
also must be unsigned integer types from the same category, they don't have to cover the whole category and in fact cannot, because there are at least 5 unsigned integer types, but you listed only three uintX_t
overloads. So size_t
doesn't need to match any of them and in fact doesn't need to match any uintX_t
at all.
For example on 64bit architectures, often uint16_t
is unsigned short
, uint32_t
is unsigned int
and uint64_t
is either unsigned long
or unsigned long long
, with the remaining one not being aliased by any uintX_t
.
So the overload set is not safe. size_t
may be one of the uintX_t
or it may not and neither the whole uintX_t
set, nor the whole set including size_t
must cover the set of all unsigned integer types.
If you want to overload for all unsigned integer types, overload by the actual (non-alias) type names for the standard unsigned integer types listed above, as well as all extended unsigned integer types if your implementation has them. However, consider whether a template, possibly constrained with a type trait, isn't a better option instead, since you can't portably know about extended integer types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With