overflows in size_t additions

Nils Pipenbrinck picture Nils Pipenbrinck · Oct 15, 2008 · Viewed 7.7k times · Source

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!

Answer

Michael Burr picture Michael Burr · Oct 15, 2008

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 that size_t always be an unsigned type. For compatibility with existing systems' header files, GCC defines size_t in stddef.h to be whatever type the system's sys/types.h defines it to be. Most Unix systems that define size_t in sys/types.h, define it to be a signed type. Some code in the library depends on size_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 of size_t as a signed type is incorrect. We plan that in version 2.4, GCC will always define size_t as an unsigned type, and the 'fixincludes' script will massage the system's sys/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 for size_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.