将 32 位旧代码移植到 64 位时如何处理更改数据类型大小?

How to handle changing data type sizes when porting 32-bit legacy code to 64-bit?

本文关键字:处理 数据类型 代码 何处理      更新时间:2023-10-16

我们的团队正在将一个10+年前的遗留代码库移植到64位(即第一步将其编译为Win64)。我们的要求是代码既编译没有警告(在/W4),又我们的 lint 工具(PC-LINT)也不会抱怨。

我们有很多类似的问题,所以在这里我举一个作为例子:

void MyFunction(size_t n) {
long tmp = n;
Call3rdPartyApiThatTakesLongArgument(tmp);
}

这给出了有关变量大小不匹配的警告和 lint 错误,因为size_t在 Win64 上增长到 64 位,而long保持在 32 位。我们目前的目标是在static_castlong之前,边界检查n以确保它适合tmp。然后,此检查会给我们另一个关于将无符号与已签名进行比较的警告。
我们最终得到的是一个巨大的宏,它利用decltype()std::make_signedstd::make_unsigned之类的东西,允许我们在没有警告的情况下进行边界检查和投射,即便如此,我们也不得不为我们在语义上知道的情况禁用一些 lint 警告。

该函数现在如下所示:

void MyFunction(size_t n) {
BOUNDSCHECK(long, n) // make sure n fits into long
long tmp = static_cast<long>(n);
Call3rdPartyApiThatTakesLongArgument(tmp);
}

使用decltypestd::make_signed等东西真的感觉不对 - 有没有更好的方法来实现我们正在努力做的事情?我们可能不是第一个将 Win32 应用程序移植到 Win64 的人,但我们在 Google 的共同努力并没有产生任何远程有用的东西......

编辑:MyFunction的签名也不在我们的控制之下,所以不幸的是,将n更改为long不是一个选项。

size_t转换为long是一种缩小的转换。因此,据我所知,没有完美的转换。

我会将您的宏转换为模板函数。然后,您可以决定如何处理错误。 您可以将 API 更改为 long(但我认为这是它size_t的原因)。

所以你必须决定当你的size_t不适合long时你会怎么做。

相关文章: