C语言 如何安全地从 int 转换为 size_t ?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27490762/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I convert to size_t from int safely?
提问by Martin
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 类型。
EDITModified as per chux' comment.
编辑根据 chux 的评论修改。
回答by dembones
To avoid compiler warnings in GCC, limit the action performed by a single cast operation to one of the following:
为了避免 GCC 中的编译器警告,请将单个强制转换操作执行的操作限制为以下之一:
- truncation or extension
- cast away signed-ness or unsigned-ness
- cast away const-ness or non-const-ness
- 截断或扩展
- 抛弃有符号或无符号
- 抛弃常量性或非常量性
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.
size_t 总是一个足够大的无符号类型,可以容纳一个空指针。从 int 到 size_t 的转换涉及两个转换操作:扩展,然后抛弃签名。
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.
这是在 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);
}

