在编译具有基于条件的类型不匹配的模块时,Delphi 编译器是否总是会失败?

Will Delphi compiler always fail when compiling a module with conditional-based type mismatch?

举个实际的例子,假设 ModuleA 在条件编译时有一些类型变化:

unit ModuleA;

interface

type
  { explicit character width }
  PASTR = type PAnsiChar;
  PWSTR = type PWideChar;
  { imlicit character width }
  PTSTR = {$IFDEF UNICODE}PWSTR{$ELSE}PASTR{$ENDIF};

  { ... }

现在 ModuleB 中的函数集取决于 ModuleA 中声明的类型:

unit ModuleB;

{ ... }    

implementation

uses ModuleA;

{ explicit }
function FuncA(Arg: PASTR): Integer;
begin
  { do something with 1 byte char }
end;

function FuncW(Arg: PWSTR): Integer;
begin
  { do something with 2 byte char }
end;

{ implicit - will compiler safeguard against mismatching UNICODE define? }
function Func(Arg: PTSTR): Integer;
begin
  { map to explicit one }
  Result := {$IFDEF UNICODE}FuncW(Arg){$ELSE}FuncA(Arg){$ENDIF};
end;

现在,假设 ModuleA 已编译并定义了 UNICODE 符号,并且已生成 DCU 文件。然后 ModuleB 仅使用没有 UNICODE 符号的 DCU 信息进行编译(反之亦然 - ModuleA.dcu 生成为 ANSI,然后尝试在 Unicode [=14] 中使用它=]).

在编译具有这种基于条件的类型不匹配的模块时,Delphi编译器总是会失败吗?使用 type 关键字和不使用它?是否有任何特定于版本的行为?

作为奖励:我对 Free Pascal 也很感兴趣。

是也不是,如果你引入了 UNICODE 符号的 DEF 或 UNDEF,你可能会破坏它,有效地覆盖你在编译时传入的指令。

虽然不确定您为什么会做这种愚蠢的事情。

想不出任何基于版本的差异,不破解将是一个灾难性的错误。

在这种情况下,编译器将无法编译程序。在 Delphi 和 FPC 中。

一种思考方式是扩展条件代码。一旦以这种方式编写,编译器将做什么就变得更加清晰。这是正确的心智模型,因为编译器就是这样处理条件代码的。它根本看不到不活动的条件分支中的代码。

考虑这两个单位:

unit Unit1;
// expanded with UNICODE defined

interface

type
  PASTR = type PAnsiChar;
  PWSTR = type PWideChar;
  PTSTR = PWSTR;

implementation

end.

unit Unit2;
// expanded with UNICODE undefined

interface

implementation

uses
  Unit1;

function FuncA(Arg: PASTR): Integer;
begin
end;

function FuncW(Arg: PWSTR): Integer;
begin
end;

function Func(Arg: PTSTR): Integer;
begin
  Result := FuncA(Arg);
end;

end.

PTSTR 的定义在 Unit1 中找到,它是 PWSTR 的别名。因此,对 FuncA 的调用将无法编译。

使用 type 来创建不同的类型也没有任何改变,因为 PAnsiCharPWideChar 已经不兼容。