64 位上的 int 与 size_t [英] int vs size_t on 64bit

查看:38
本文介绍了64 位上的 int 与 size_t的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将代码从 32 位移植到 64 位.很多地方有

Porting code from 32bit to 64bit. Lots of places with

int len = strlen(pstr);

这些现在都会产生警告,因为 strlen() 返回 size_t 是 64 位而 int 仍然是 32 位.所以我一直用

These all generate warnings now because strlen() returns size_t which is 64bit and int is still 32bit. So I've been replacing them with

size_t len = strlen(pstr);

但我刚刚意识到这并不安全,因为 size_t 是未签名的,可以将其视为由代码签名(我实际上遇到了一个导致问题的情况,谢谢,单元测试!).

But I just realized that this is not safe, as size_t is unsigned and it can be treated as signed by the code (I actually ran into one case where it caused a problem, thank you, unit tests!).

盲目地将 strlen 返回到 (int) 感觉很脏.或者它不应该?
所以问题是:有没有一个优雅的解决方案?我的代码库中可能有一千行这样的代码;我无法手动检查每一个,测试覆盖率目前在 0.01 到 0.001% 之间.

Blindly casting strlen return to (int) feels dirty. Or maybe it shouldn't?
So the question is: is there an elegant solution for this? I probably have a thousand lines of code like that in the codebase; I can't manually check each one of them and the test coverage is currently somewhere between 0.01 and 0.001%.

推荐答案

作为妥协,您可以使用 ssize_t(如果可用).如果没有,请使用 long longint_fast64_tintmax_t 或使用平台移植标头来为平台.ssize_t 在 POSIX 中不是标准的 C 或 C++,但是如果您遇到过的平台没有与 size_t 相同大小的签名类型,那么我很同情.

As a compromise, you could use ssize_t (if available). Fake it up if not, using long long, int_fast64_t, intmax_t, or have a platform porting header which lets a suitable type be specified for a platform. ssize_t is in POSIX not standard C or C++, but if you ever hit a platform which doesn't have a signed type of the same size as size_t then I sympathise.

转换为 int 几乎是安全的(假设在您的 64 位平台上是 32 位 int,这似乎是合理的),因为字符串的长度不太可能超过 2^31 个字节.转换为更大的签名类型甚至更安全.能够负担 2^63 字节内存的客户在业内被称为一个好问题";-)

A cast to int is nearly safe (assuming 32 bit int on your 64 bit platform, which seems reasonable), because a string is unlikely to be more than 2^31 bytes long. A cast to a larger signed type is even safer. Customers who can afford 2^63 bytes of memory are what's known in the trade as "a good problem to have" ;-)

当然,你可以检查一下:

Of course, you could check it:

size_t ulen = strlen(pstr);
if (ulen > SSIZE_MAX) abort(); // preferably trace, log, return error, etc.
ssize_t len = (ssize_t) ulen;

当然有开销,但如果您有 1000 个实例,那么它们不可能都是性能关键的.对于那些(如果有的话),你可以调查 len 被签名是否真的很重要.如果没有,请切换到 size_t.如果是这样,请重写或只是冒险永远不会遇到如此巨大的对象.如果 len 由于 strlen 返回大于 INT_MAX 的值而为负,那么原始代码几乎肯定会在 32 位平台上做错事.

Sure there's an overhead, but if you have 1000 instances then they can't all be performance-critical. For the ones which are (if any), you can do the work to investigate whether len being signed actually matters. If it doesn't, switch to size_t. If it does, rewrite or just take a risk on never meeting an object that absurdly huge. The original code would almost certainly have done the wrong thing anyway on the 32bit platform, if len had been negative as a result of strlen returning a value bigger than INT_MAX.

这篇关于64 位上的 int 与 size_t的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆