【问题标题】:Porting Delphi code to 64 bit - Why no compiler warnings?将 Delphi 代码移植到 64 位 - 为什么没有编译器警告?
【发布时间】:2011-12-22 07:36:43
【问题描述】:

我们有一个大型的 Delphi XE 代码库,希望移植到 64 位。

我拥有 Delphi XE2 许可证,但我找不到任何警告或提示可以帮助我检测有效的 32 位结构,这些结构现在可能导致 64 位平台下的数据丢失。例如,对于 32 位编译器完全有效的 THandleCardinal 分配在为 Win64 编译时不会引发任何警告。

在使用 Delphi 2009 迁移到 Unicode 时,我们收到了大量警告,这些警告对我们跟踪和修复可疑代码很有帮助。使用 XE2,我什么也找不到。我无法想象在编译器级别没有集成任何东西来避免我们对所有代码进行手动审查。

我错过了什么吗?如果您尝试过,您是如何将项目移植到 64 位的?

谢谢!

【问题讨论】:

  • THandle 不再映射到integer,而是映射到NativeUInt(即只有Win32下的cardinal)。这可能有助于确定问题。
  • 我似乎也无法在 XE (1) 中获取此类消息,例如将 int 分配给字节...
  • @GolezTrol :你是对的,但是从我的 POV 分配来看,当它们为 Win32 或 Win64 编译时可能会导致不同的结果,应该引入一类新的编译器警告.

标签: windows delphi 64-bit delphi-xe2 win64


【解决方案1】:

大约 5 年前,我将它们移植到 64 位 Free Pascal。 (即使只有带有简单单元测试的部件来检测它们)

使用这两种编译器进行测试只会发现更多问题。

【讨论】:

  • 谢谢...不过,我觉得有点令人沮丧的是,您必须使用两个编译器来规避您以高价购买的官方版本的限制!
  • @Adrien,是什么让你觉得 Delphi 是官方 Pascal 编译器?
  • 好吧,如果你想编译 Delphi 代码,AFAIK dcc64.exe 是“官方”的 64 位 Delphi 编译器。
  • 在我的一生中,我看不出帕斯卡是从哪里来的。这是一个关于 XE2 64 位 Windows 目标的问题。
  • David Heffernan:我的应用做到了。但是我可以通过创建 DPR 并导入一些单元来轻松编译大型部件。对于警告就足够了。 DelphiFPC 兼容性的情况并没有你想象的那么糟糕。听起来你曾经尝试过一次,并期望它会是一次盲目的编译,这让你很生气。这当然不是免费乘车,但这并不意味着它不可能或无用。仅当您使用例如每个单元都有Datasnap,那么它是非常无望的。
【解决方案2】:

你没有错过任何东西。产品中没有任何东西可以帮助您。

我也觉得这有点令人失望,但我完全希望 Emba 设计师考虑到这一点。我只能得出结论,他们的经验是添加此类警告导致的噪音多于信号。 Delphi 编译器在分配给不兼容的整数类型时从未发出警告。例如,将整数分配给字节从来都不是警告或错误。

是时候启动 grep 并搜索 Integer\(.*\)Longint\(.*\)Cardinal\(.*\)Longword\(.*\)THandle 等了。


为了回应 Arnaud 的评论和回答,我提供了以下代码,该代码在针对 64 位时编译时不会出现警告和错误。

procedure NaughtyCode;
var
  Handle: THandle;
  int: Integer;
  card: Cardinal;
  P: Pointer;
begin
  Handle := high(Handle);
  int := Handle;
  card := Handle;
  P := Pointer(Handle);
  int := Integer(P);
  card := Cardinal(P);
end;

【讨论】:

  • 我无法理解为什么他们没有包含任何可以简化流程的可选警告...类型转换是一回事,但正如我所说,在 Win64 下分配来自/到具有不同大小的数据类型(例如,THandle) 更难以 grep,并且还可能导致数据丢失/数据损坏。我真的不明白他们的选择。
  • 通过使用 grep,搜索是可以的,但每个人都应该注意不要将它用于整个“替换”选项 - 这肯定会破坏代码。在所有情况下,当在 Win64 下编译时,THandlepointerinteger() 类型转换将引发显式编译器错误。因此恕我直言,搜索不是强制性的:当将目标平台设置为 Win64 时,编译器会为您特意进行搜索。
  • @Arnaud 我一定是做错了什么。您如何配置 XE2 以针对我添加到问题中的代码发出警告或错误?
  • 我支持你大卫。编译此类代码时我没有收到任何错误。
  • 同意显式类型转换。但是我所说的“跨平台的不可移植任务”呢,其中所涉及类型的大小会根据目标平台而变化?
【解决方案3】:

正如您所说,大部分潜在问题来自:

  • WinAPI 更改(但大部分时间相同/兼容);
  • THandle不再映射到integer,而是映射到NativeUInt(即Win32下才有cardinal);
  • 在指针算术中,Integer 类型转换未映射到 NativeInt

最新版本会引发编译器错误,不仅是警告(它是显式类型不匹配),而且THandle 的更改应该被警告为。

我不会对 Embarcadero 的主编译器那么苛刻 - 我更关心后台编译器(例如 CodeInsight)是 not synchronized with the main compiler。对我来说,主编译器工作正常,我从不抱怨缺少警告。明确搜索THandle 并不难。

【讨论】:

  • 请查看我更新的问题。据我所知,你在这个答案中所说的实际上是不正确的。我不会投反对票,因为我尊重你总是准确的事实,而且我很可能只是忽略了一些事情。那么请问,我忽略了什么?
猜你喜欢
  • 1970-01-01
  • 2010-12-01
  • 2011-04-30
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-29
  • 1970-01-01
相关资源
最近更新 更多