diff options
Diffstat (limited to 'lib/xsize.h')
-rw-r--r-- | lib/xsize.h | 28 |
1 files changed, 24 insertions, 4 deletions
diff --git a/lib/xsize.h b/lib/xsize.h index 71c9c073..5ae86006 100644 --- a/lib/xsize.h +++ b/lib/xsize.h @@ -26,7 +26,7 @@ /* Get size_t. */ #include <stddef.h> -/* Get SIZE_MAX. */ +/* Get INT_MAX, SIZE_MAX. */ #include <limits.h> #if HAVE_STDINT_H # include <stdint.h> @@ -40,6 +40,11 @@ _GL_INLINE_HEADER_BEGIN # define XSIZE_INLINE _GL_INLINE #endif +#ifdef __cplusplus +extern "C" { +#endif + + /* The size of memory objects is often computed through expressions of type size_t. Example: void* p = malloc (header_size + n * element_size). @@ -56,7 +61,8 @@ _GL_INLINE_HEADER_BEGIN void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); */ -/* Convert an arbitrary value >= 0 to type size_t. */ +/* Convert an arbitrary N >= 0 to type size_t. + N should not have side effects. */ #define xcast_size_t(N) \ ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) @@ -64,8 +70,15 @@ _GL_INLINE_HEADER_BEGIN XSIZE_INLINE size_t ATTRIBUTE_PURE xsum (size_t size1, size_t size2) { - size_t sum = size1 + size2; - return (sum >= size1 ? sum : SIZE_MAX); + if (INT_MAX < SIZE_MAX) + { + /* Optimize for the common case where size_t arithmetic wraps + around without undefined behavior. */ + size_t sum = size1 + size2; + return size1 <= sum ? sum : SIZE_MAX; + } + + return size1 <= SIZE_MAX - size2 ? size1 + size2 : SIZE_MAX; } /* Sum of three sizes, with overflow check. */ @@ -93,6 +106,8 @@ xmax (size_t size1, size_t size2) /* Multiplication of a count with an element size, with overflow check. The count must be >= 0 and the element size must be > 0. + Arguments should not have side effects. + The element size's type should be no wider than size_t. This is a macro, not a function, so that it works correctly even when N is of a wider type and N > SIZE_MAX. */ #define xtimes(N, ELSIZE) \ @@ -105,6 +120,11 @@ xmax (size_t size1, size_t size2) #define size_in_bounds_p(SIZE) \ ((SIZE) != SIZE_MAX) + +#ifdef __cplusplus +} +#endif + _GL_INLINE_HEADER_END #endif /* _XSIZE_H */ |