问题描述
移植code,从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是无符号的,由code作为签字可以治疗(我居然遇到了一种情况就引起了问题,谢谢,单元测试!)
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)感觉很脏。或者,也许它不应该?结果
所以,问题是:是否有一个这样的优雅的解决方案?我大概有一千行code一样,在codeBase类的;我不能手动检查他们中的每一个和测试覆盖范围目前介于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供
(如果可用)。假的了,如果没有,使用长长
, int_fast64_t
,还会将intmax_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
。如果是这样,重写或只承担从未见面的对象荒谬的巨大风险。原来的code几乎肯定会反正做了错误的事情32位平台上,如果 LEN
一直否定的,因为中的strlen 返回大的值大于
INT_MAX
。
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
.
这篇关于诠释VS在64位为size_t的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!