I like to have my code warning free for VS.NET and GCC, and I like to have my code 64-bit ready.
Today I wrote a little module that deals with in memory buffers and provides access to the data via a file-style interface (e.g. you can read bytes, write bytes, seek around etc.).
As the data-type for current read position and size I used size_t since that seems to be the most natural choice. I get around the warnings and it ought to work in 64-bit as well.
Just in case: My structure looks like this:
typedef struct
{
unsigned char * m_Data;
size_t m_CurrentReadPosition;
size_t m_DataSize;
} MyMemoryFile;
The signedness of size_t
seems not to be defined in practice. A Google code-search proved that.
Now I'm in a dilemma: I want to check additions with size_t
for overflows because I have to deal with user supplied data and third party libraries will use my code. However, for the overflow check I have to know the sign-ness. It makes a huge difference in the implementation.
So - how the heck should I write such a code in a platform and compiler independent way?
Can I check the signedness of size_t
at run or compile-time? That would solve my problem. Or maybe size_t
wasn't the best idea in the first place.
Any ideas?
EDIT: I'm looking for a solution for the C-language!
Write a “C” function, int addOvf(int* result, int a, int b) If there is no overflow, the function places the resultant = sum a+b in “result” and returns 0. Otherwise it returns -1. The solution of casting to long and adding to find detecting the overflow is not allowed.
Yes, size_t is guaranteed to be an unsigned type.
In short, ssize_t is the same as size_t , but is a signed type - read ssize_t as “signed size_t ”. ssize_t is able to represent the number -1 , which is returned by several system calls and library functions as a way to indicate error.
size_t is guaranteed to be able to hold the number of bytes of any object on your implementation. That's why the return type of sizeof is size_t . So yes, it's portable.
Regarding the whether size
_t is signed or unsigned and GCC (from an old GCC manual - I'm not sure if it's still there):
There is a potential problem with the
size_t
type and versions of GCC prior to release 2.4. ANSI C requires thatsize_t
always be an unsigned type. For compatibility with existing systems' header files, GCC definessize_t
instddef.h
to be whatever type the system'ssys/types.h
defines it to be. Most Unix systems that definesize_t
insys/types.h
, define it to be a signed type. Some code in the library depends onsize_t
being an unsigned type, and will not work correctly if it is signed.The GNU C library code which expects
size_t
to be unsigned is correct. The definition ofsize_t
as a signed type is incorrect. We plan that in version 2.4, GCC will always definesize_t
as an unsigned type, and the 'fixincludes' script will massage the system'ssys/types.h
so as not to conflict with this.In the meantime, we work around this problem by telling GCC explicitly to use an unsigned type for
size_t
when compiling the GNU C library. 'configure' will automatically detect what type GCC uses forsize_t
arrange to override it if necessary.
If you want a signed version of size_t
use ptrdiff_t
or on some systems there is a typedef for ssize_t
.
size_t
is an unsigned integral type, according to the C++ C standards. Any implementation that has size_t
signed is seriously nonconforming, and probably has other portability problems as well. It is guaranteed to wrap around when overflowing, meaning that you can write tests like if (a + b < a)
to find overflow.
size_t
is an excellent type for anything involving memory. You're doing it right.
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