我们的团队正在将 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_cast
将其转换为 long
之前,对 n 进行边界检查以确保它适合 tmp
。然后,此检查会向我们发出另一个关于比较未签名和已签名的警告。
我们最终得到的是一个巨大的宏,它利用诸如 decltype()
、std::make_signed
和 std::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);
}
使用 decltype
和 std::make_signed
等东西真的感觉不对 - 有没有更好的方法来实现我们正在尝试做的事情?我们可能不是第一个将 Win32 应用程序移植到 Win64 的人,但我们与 Google 的共同努力并没有产生任何有用的东西......
编辑:MyFunction 的签名也不在我们的控制之下,因此不幸的是,将 n 更改为 long 不是一个选项。
最佳答案
convert from size_t
to long
是缩小转换。因此,据我所知,不可能有完美的转换。
我会将您的宏转换为模板函数。然后您可以决定如何处理错误。
您可以将 API 更改为 long(但我认为这是 size_t
的原因)。
因此,当您的 size_t
不适合 long
时,您必须决定要做什么。
关于c++ - 将 32 位遗留代码移植到 64 位时如何处理不断变化的数据类型大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57215835/