I had been using size_t
and ssize_t
in my code without thinking much about them.
I moved some code into a new file, and found that it no longer compiled, because the appropriate headers for size_t
and ssize_t
were missing.
A quick search suggests that size_t
is a "C-style" type, and can be obtained from a variety of headers.
The most fundamental one appears to be stddef.h
.
On the other hand, ssize_t
appears to be a Linux specific thing. (I'm unsure about this.)
Where is ssize_t defined in Linux?
I can't find anything which suggests std::ssize_t
exists.
On the other hand, std::size_t
does exist. It can be obtained from cstddef
, among others.
It would seem to make sense to prefer std::size_t
over size_t
if one wanted to write a more C++ looking code, although I assume there is no difference between size_t
and std::size_t
.
Why isn't ssize_t
part of the standard library, and does this mean that this definition is not portable?
I had been using size_t
and ssize_t
in my code without thinking much about them.
I moved some code into a new file, and found that it no longer compiled, because the appropriate headers for size_t
and ssize_t
were missing.
A quick search suggests that size_t
is a "C-style" type, and can be obtained from a variety of headers.
The most fundamental one appears to be stddef.h
.
https://en.cppreference/w/c/types/size_t
On the other hand, ssize_t
appears to be a Linux specific thing. (I'm unsure about this.)
Where is ssize_t defined in Linux?
I can't find anything which suggests std::ssize_t
exists.
On the other hand, std::size_t
does exist. It can be obtained from cstddef
, among others.
https://en.cppreference/w/cpp/types/size_t
It would seem to make sense to prefer std::size_t
over size_t
if one wanted to write a more C++ looking code, although I assume there is no difference between size_t
and std::size_t
.
Why isn't ssize_t
part of the standard library, and does this mean that this definition is not portable?
2 Answers
Reset to default 4I would speculate that the primary issue is that size_t is unsigned, and there's an assumption that one could take size_t and assign it into a ssize_t without overflow (i.e. it shouldn't be possible for an object to be so large that if size_t were signed it would become negative). This could be the case on i.e embedded processors with segmented memory where size_t may be reasonably small (16 or 8 bits) and so an object (or array of objects) could be reasonably expected to be larger than half the range of size_t.
If you look at how the standard defines std::ssize() (which is supposed to return a signed version of a container's size) you'll see how "signed size" is actually articulated:
std::common_type_t<std::ptrdiff_t, std::make_signed_t<decltype(c.size())>>
Or in english: "a type that both the difference between two pointers and the signed version of the size of the container (usually size_t) can be implicitly converted to".
For C-style arrays this is simplified to just std::ptrdiff_t.
For most machines (although I can't think of any where this wouldn't be the case, unless you had some exotic container that could hold more objects that could be counted in a ptrdiff_t by storing them on disk or something) that's probably going to be std::ptrdiff_t for all containers, which indicates a signed type that's capable of expressing the distance between two pointers, or put another way a type that's capable of expressing the difference between a pointer to the end of an array and a pointer to the start of an array.
On the aforementioned machines with small size_t, this is probably larger than size_t since the largest positive value it needs to be able to hold is the maximum size of an object, and so if the maximum size is the maximum value of size_t you'll need to go at least 1 bit larger to fit the negatives.
As to why there simply isn't a define for ssize_t = ptrdiff_t in the standard, that's probably just because nobody has proposed it. The idea that ssize_t might have to be larger than size_t could be surprising enough that there's a desire to have people use the more descriptive name of ptrdiff_t rather than ssize_t.
Why isn't
ssize_t
part of the standard library?
Because neither of the standard functions return ssize_t
. If standard functions need to return negative values then they return the standard ptrdiff_t
. (size_t
assumes some count, ptrdiff_t
assumes some offset.)
ssize_t
is of POSIX and assumes either count or the error indicator -1. The type is not portable and not used in Windows AFAIK.
ptrdiff_t
withrecv
, in place ofssize_t
? That doesn't seem very sensible thinking about it. What is the return type for Windows equivalent ofrecv
? – user2138149 Commented Feb 15 at 16:00recv
is not C++. I don't follow your question. If you userecv
then you#include <sys/socket.h>
and can use ssize_t. Windowsrecv
returnsint
. – 3CxEZiVlQ Commented Feb 15 at 16:03std::expected
. I program in Rust for a month, and look what happens. – Eljay Commented Feb 15 at 19:27