简体   繁体   English

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

[英]How can I convert to size_t from int safely?

Assigning an int to a size_t (or using it in malloc) in GCC produces the following warning: 在GCC中将int赋给size_t(或在malloc中使用它)会产生以下警告:

warning: conversion to 'size_t' from 'int' may change the sign of the result [-Wsign-conversion] 警告:从'int'转换为'size_t'可能会更改结果的符号[-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. 我能找到的最接近的东西是Microsoft Intsafe.h ,但它似乎只适用于Win32类型。

EDIT Modified as per chux' comment. 编辑修改按照chux'评论。

To avoid compiler warnings in GCC, limit the action performed by a single cast operation to one of the following: 要避免GCC中的编译器警告,请将单个强制转换操作执行的操作限制为以下之一:

  1. truncation or extension 截断或扩展
  2. cast away signed-ness or unsigned-ness 抛弃签名或无签名
  3. cast away const-ness or non-const-ness 抛弃常数或非常数

size_t is always an unsigned type large enough to hold a void pointer. size_t始终是一个无符号类型,足以容纳void指针。 Casting from int to size_t involves two cast operations: extend, then cast away signed-ness. 从int到size_t的转换涉及两个强制转换操作:extend,然后抛弃signed-ness。

Here's two functions that produce no compiler warnings (with '-Wall -Werror -Wextra') on GCC 4.8.3. 这两个函数在GCC 4.8.3上没有产生编译器警告(使用'-Wall -Werror -Wextra')。 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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM