在编译具有基于条件的类型不匹配的模块时,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
来创建不同的类型也没有任何改变,因为 PAnsiChar
和 PWideChar
已经不兼容。
举个实际的例子,假设 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
来创建不同的类型也没有任何改变,因为 PAnsiChar
和 PWideChar
已经不兼容。