c++ - 将 32 位遗留代码移植到 64 位时如何处理不断变化的数据类型大小?

标签 c++ 64-bit x86-64 32bit-64bit porting

我们的团队正在将 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_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 不是一个选项。

最佳答案

convert from size_t to long 是缩小转换。因此,据我所知,不可能有完美的转换。

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

因此,当您的 size_t 不适合 long 时,您必须决定要做什么。

关于c++ - 将 32 位遗留代码移植到 64 位时如何处理不断变化的数据类型大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57215835/

相关文章:

c++ - 如何跟踪拖放操作的生命周期?

c++ - 使用 new 和传递指针时的基本 C++ 段错误

windows - 为 32 位 PCI 设备编写 Windows 64 位设备驱动程序

C二进制达到1.2G内存限制

memory-management - gfortran傻瓜版:mcmodel = medium到底能做什么?

c++ - 二进制 '<' : 'const_Ty' does not define this operator or a conversion to a type acceptable to the predefined operator

c++ - Visual Studio 不会在配置管理器中给我 64 位的平台选项..?

assembly - 使用 gdb 检查寄存器的值

c - 单个 sqrt() 的运行速度如何比放入 for 循环时慢两倍

c++ - 使用 ostream 和链接的运算符重载。为什么要通过引用返回?