如何安全地从int转换为size_t?

时间:2014-12-15 18:34:41

标签: c casting type-conversion

在GCC中将int赋值给size_t(或在malloc中使用它)会产生以下警告:

  

警告:转换为' size_t'来自' int'可能会更改结果的符号[-Wsign-conversion]

要解决这个问题,我想将转换包装在首先检查转换是否有效的函数中,然后进行转换。

这是我到目前为止所做的:

/* 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;
}

我错过了什么吗?是否存在已安装转换的库?

我能找到的最接近的是Microsoft Intsafe.h,但它似乎只适用于Win32类型。

编辑按照chux&#39;进行修改评价。

1 个答案:

答案 0 :(得分:5)

要避免GCC中的编译器警告,请将单个强制转换操作执行的操作限制为以下之一:

  1. 截断或延期
  2. 抛弃已签名或无签名的
  3. 抛弃常量或非常数
  4. size_t总是一个无符号类型,足以容纳一个void指针。铸造自 int到size_t涉及两个强制转换操作:extend,然后抛弃signed-ness。

    这两个函数在GCC 4.8.3上不产生编译器警告(使用'-Wall -Werror -Wextra')。它们返回内联失败(通过哨兵值),而不是额外的返回参数。

    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);
    }