Delphi 11.1触发W1023警告:未定义编译指令的类型比较问题
关于Delphi编译FreePascal兼容代码的警告问题
我们使用的第三方软件.inc文件中有一段FreePascal兼容的32位代码:
{$IF DEFINED(fpc) and (fpc_version < 3)} if IsConstructor or IsVirtualCons then tbtu32(res.dta^) := RealCall_Register(Address, EDX, EAX, ECX, @Stack[Length(Stack) - 3], Length(Stack) div 4, 4, nil) else {$IFEND}
在Delphi 11.1编译时,{$IF DEFINED(fpc) and (fpc_version < 3)} 行会触发W1023 Comparing signed and unsigned type警告,此时fpc_version并未定义。我们可通过关闭警告或注释代码规避,两个疑问的解答如下:
疑问1:为何未定义的编译“变量”会触发该警告?
Delphi的条件编译预处理器处理{$IF}表达式时,会先解析整个表达式的语法与类型,不会因某个分支条件为假就跳过后续部分的检查。当fpc_version未定义时,Delphi会将其默认视为无符号整数类型的0,而字面量3默认是有符号整数类型。无符号值与有符号值直接比较,就触发了W1023类型不匹配警告。
疑问2:该写法是否在FreePascal中允许但Delphi中不允许?
这种写法在FreePascal中完全允许。FreePascal的预处理器支持逻辑短路求值:当DEFINED(fpc)为假时,会直接跳过fpc_version < 3的求值过程,既不会因为fpc_version未定义报错,也不会触发类型警告。但Delphi的预处理器不支持这种短路逻辑,它会对表达式的所有部分做类型解析,哪怕前面的条件已经不成立,因此会触发警告。
内容的提问来源于stack exchange,提问作者Jan Doggen
相关产品推荐
相关产品推荐

