Reputation: 6015
Assigning an int to a size_t (or using it in malloc) in GCC produces the following warning:
warning: conversion to 'size_t' from 'int' may change the sign of the result [-Wsign-conversion]
To solve this, I would like to wrap the conversion in a function that first checks if the conversion is valid, then does the cast.
This is what I have so far:
/* Convert int src to size_t dst. */
/* Assumes dst points to valid size_t address. */
int safe_size_t_from_int(size_t *dst, int src) {
if(src < 0) return SAFE_ERROR_NEGATIVE;
if(SIZE_MAX < INT_MAX) {
if(src > (int)SIZE_MAX) return SAFE_ERROR_OVERFLOW;
}
*dst = (size_t)src;
return SAFE_SUCCESS;
}
Am I missing anything? Is there a library with safe conversions that already exists?
The closest thing I can find is Microsoft Intsafe.h, but it appears to be for Win32 types only.
EDIT Modified as per chux' comment.
Upvotes: 9
Views: 30503
Reputation: 341
To avoid compiler warnings in GCC, limit the action performed by a single cast operation to one of the following:
size_t is always an unsigned type large enough to hold a void pointer. Casting from int to size_t involves two cast operations: extend, then cast away signed-ness.
Here's two functions that produce no compiler warnings (with '-Wall -Werror -Wextra') on GCC 4.8.3. They return failure inline (via sentinel values), rather than in an extra return parameter.
int size_t2int(size_t val) {
return (val <= INT_MAX) ? (int)((ssize_t)val) : -1;
}
size_t int2size_t(int val) {
return (val < 0) ? __SIZE_MAX__ : (size_t)((unsigned)val);
}
Upvotes: 10