Delphi 的编译指令

Delphi 的编译指令: $DEFINE、$UNDEF、$IFDEF、$ELSE、$ENDIF

来源:http://tech.ddvip.com/2009-04/1239360770114444.html 原排版更易阅读

    一个程序从无到有的过程是这样的: 编辑代码 -> 预处理 -> 编译(成dcu等) -> 链接(为exe等).

  什么是预处理?

  譬如 VCL 中有很多代码是兼容 Linux 的, 在 Windows 下就需要在编译之前预处理掉那些 for Linux 的代码.

  1、判断操作系统:

  其中的 "MSWINDOWS" 和 "LINUX" 就是 Delphi 预定义的 "条件标识符".

1
2
3
4
5
6
7
8
begin
{ $IFDEF  MSWINDOWS}
ShowMessage( 'Windows' );
{ $ENDIF }
{ $IFDEF  LINUX}
ShowMessage( 'Linux' );
{ $ENDIF }
end ;

  2、自定义条件标识符(DEFINE):

  下面例子中自定义了条件标识符: WanYi; 标识符和定义它的指令都不区分大小写, 但大家一般惯用大写.

1
2
3
4
5
6
7
8
begin
{ $DEFINE  WANYI}
{ $IFDEF  WanYi}
ShowMessage( '标识符 WanYi 已定义' );
{ $ELSE }
ShowMessage( '标识符 WanYi 未定义' );
{ $ENDIF }
end ;

  3、取消条件标识符的定义(UNDEF):

1
2
3
4
5
6
7
8
9
10
begin
{ $DEFINE  WANYI}
{ $IFDEF  WANYI}
ShowMessage( '确认标识符 WanYi 是否定义' );
{ $ENDIF }
{ $UNDEF  WANYI}
{ $IFDEF  WANYI}
ShowMessage( '再次确认标识符 WanYi 是否定义' );
{ $ENDIF }
end ;

  4、取消定义的简单办法:

  在 {$...} 的 $ 前面随便加点什么, 让它变成 "注释", 譬如: {.$}

1
2
3
4
5
6
7
8
9
10
begin
{.$DEFINE WANYI}
{ $IFDEF  WANYI}
ShowMessage( '确认标识符 WanYi 是否定义' );
{ $ENDIF }
{.$UNDEF WANYI}
{ $IFDEF  WANYI}
ShowMessage( '再次确认标识符 WanYi 是否定义' );
{ $ENDIF }
end ;

  5、调试编译指令时特别要注意的:

  Delphi 有个常识: 如果单元代码没有改变, 相应的 dcu 不会重新生成!

  因此, 为了有准确的调试结果, 执行前先用 Shift+F9 强制编译当前工程, 然后再 Run;

  强制编译所有相关单元也可以, 方法: Project -> Build all project.

  当然修改下代码也很方便, 譬如在代码中打个空格再退回来.

  6、测试预定义的 Debug 和 Release:

  当我们当新建一个工程, Delphi 默认的是调试(Debug)状态, 当我们发布软件时应该切换到发布(Release)状态.

  两种状态下编译指令是有区别的, 在 Release 状态下发布的 dcu 或 exe 会更小、更优化.

  Debug 和 Release 的切换方法:

  进入 Project Manager -> Build Configurations, 在 Debug 或 Release 上双击, 或从右键 Activate.

  下面的代码可以检测到这种改变, 不过要注意上面提到的 Shift+F9 或 Project -> Build all project.

1
2
3
4
5
6
7
8
begin
{ $IFDEF  DEBUG}
ShowMessage( '调试模式' );
{ $ENDIF }
{ $IFDEF  RELEASE}
ShowMessage( '发布模式' );
{ $ENDIF }
end ;

  7、编译指令写在哪?:

  编译指令可以写在代码页的任何地方, 不过在代码的不同区域有时也会不同;

  譬如: {$APPTYPE GUI} 和 {$APPTYPE CONSOLE} 就只能写在工程文件里才有效.

  {$APPTYPE GUI} 和 {$APPTYPE CONSOLE} 分别表示窗口工程和控制台工程.

  其中 {$APPTYPE GUI} 是默认的, 所以很少见到它.

  它甚至可以嵌入到代码行当中, 譬如 ActnColorMaps 单元就有这么一句:

1
2
3
begin
SystemParametersInfo(SPI_GETFLATMENU,  0 , { $IFNDEF  CLR}@{ $ENDIF }FlatMenus,  0 );
end ;

  8、条件标识符的有效范围:

  Delphi 预定义的条件标识符都是全局的, 我们用 {$DEFINE ...} 自定义的标识符都是局部的.

  如何自定义全局的标识符呢?

  Project -> Options... -> 选定 Delphi Compiler -> 点击 Conditional defines 右边小按钮 -> 添加.

  不过这和系统预定义的还是有区别, 咱们自定义的只能用于当前文件.

  如何定义每个文件都可以使用的标识符呢?

  从 Project -> Options... 定义后, 马上选择左下角的 Default.

  这和系统预定义的还是有区别, 因为这只能左右以后的文件, 管不着以前存在的文件.

  如何...没办法了.

  其他编译指令, 譬如在 Debug 或 Release 中的设置也都是这样; 也就是说: 每个文件都有相对独立的编译设置.

  看到 Project -> Options... 马上明白了编译指令的设置方法有两种:

1、使用 {$...} 在代码中嵌入;

  2、从 Project -> Options... 设置.

  但在代码中嵌入有时是不可替代的, 譬如现在讨论的条件编译.

  9、编译指令有多少?:

  现在谈到的还只是条件编译, 实际应用最多的是开关编译; 在任一代码页执行快捷键 Ctrl+O+O , 然后看看最上面...

  下面列出了这些默认设置:

双击代码全选
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
{ $A8 ,B-,C+,D+,E-,F-,G+,H+,I+,J-,K-,L+,M-,N-,O+,P+,Q-,R-,S-,T-,U-,V+,W-,X+,Y+,Z1}
{ $MINSTACKSIZE   $00004000 }
{ $MAXSTACKSIZE   $00100000 }
{ $IMAGEBASE   $00400000 }
{ $APPTYPE  GUI}
{ $WARN  SYMBOL_DEPRECATED  ON }
{ $WARN  SYMBOL_LIBRARY  ON }
{ $WARN  SYMBOL_PLATFORM  ON }
{ $WARN  SYMBOL_EXPERIMENTAL  ON }
{ $WARN  UNIT_LIBRARY  ON }
{ $WARN  UNIT_PLATFORM  ON }
{ $WARN  UNIT_DEPRECATED  ON }
{ $WARN  UNIT_EXPERIMENTAL  ON }
{ $WARN  HRESULT_COMPAT  ON }
{ $WARN  HIDING_MEMBER  ON }
{ $WARN  HIDDEN_VIRTUAL  ON }
{ $WARN  GARBAGE  ON }
{ $WARN  BOUNDS_ERROR  ON }
{ $WARN  ZERO_NIL_COMPAT  ON }
{ $WARN  STRING_CONST_TRUNCED  ON }
{ $WARN  FOR_LOOP_VAR_VARPAR  ON }
{ $WARN  TYPED_CONST_VARPAR  ON }
{ $WARN  ASG_TO_TYPED_CONST  ON }
{ $WARN  CASE_LABEL_RANGE  ON }
{ $WARN  FOR_VARIABLE  ON }
{ $WARN  CONSTRUCTING_ABSTRACT  ON }
{ $WARN  COMPARISON_FALSE  ON }
{ $WARN  COMPARISON_TRUE  ON }
{ $WARN  COMPARING_SIGNED_UNSIGNED  ON }
{ $WARN  COMBINING_SIGNED_UNSIGNED  ON }
{ $WARN  UNSUPPORTED_CONSTRUCT  ON }
{ $WARN  FILE_OPEN  ON }
{ $WARN  FILE_OPEN_UNITSRC  ON }
{ $WARN  BAD_GLOBAL_SYMBOL  ON }
{ $WARN  DUPLICATE_CTOR_DTOR  ON }
{ $WARN  INVALID_DIRECTIVE  ON }
{ $WARN  PACKAGE_NO_LINK  ON }
{ $WARN  PACKAGED_THREADVAR  ON }
{ $WARN  IMPLICIT_IMPORT  ON }
{ $WARN  HPPEMIT_IGNORED  ON }
{ $WARN  NO_RETVAL  ON }
{ $WARN  USE_BEFORE_DEF  ON }
{ $WARN  FOR_LOOP_VAR_UNDEF  ON }
{ $WARN  UNIT_NAME_MISMATCH  ON }
{ $WARN  NO_CFG_FILE_FOUND  ON }
{ $WARN  IMPLICIT_VARIANTS  ON }
{ $WARN  UNICODE_TO_LOCALE  ON }
{ $WARN  LOCALE_TO_UNICODE  ON }
{ $WARN  IMAGEBASE_MULTIPLE  ON }
{ $WARN  SUSPICIOUS_TYPECAST  ON }
{ $WARN  PRIVATE_PROPACCESSOR  ON }
{ $WARN  UNSAFE_TYPE OFF}
{ $WARN  UNSAFE_CODE OFF}
{ $WARN  UNSAFE_CAST OFF}
{ $WARN  OPTION_TRUNCATED  ON }
{ $WARN  WIDECHAR_REDUCED  ON }
{ $WARN  DUPLICATES_IGNORED  ON }
{ $WARN  UNIT_INIT_SEQ  ON }
{ $WARN  LOCAL_PINVOKE  ON }
{ $WARN  MESSAGE_DIRECTIVE  ON }
{ $WARN  TYPEINFO_IMPLICITLY_ADDED  ON }
{ $WARN  RLINK_WARNING  ON }
{ $WARN  IMPLICIT_STRING_CAST  ON }
{ $WARN  IMPLICIT_STRING_CAST_LOSS  ON }
{ $WARN  EXPLICIT_STRING_CAST OFF}
{ $WARN  EXPLICIT_STRING_CAST_LOSS OFF}
{ $WARN  CVT_WCHAR_TO_ACHAR OFF}
{ $WARN  CVT_NARROWING_STRING_LOST OFF}
{ $WARN  CVT_ACHAR_TO_WCHAR OFF}
{ $WARN  CVT_WIDENING_STRING_LOST OFF}
{ $WARN  XML_WHITESPACE_NOT_ALLOWED  ON }
{ $WARN  XML_UNKNOWN_ENTITY  ON }
{ $WARN  XML_INVALID_NAME_START  ON }
{ $WARN  XML_INVALID_NAME  ON }
{ $WARN  XML_EXPECTED_CHARACTER  ON }
{ $WARN  XML_CREF_NO_RESOLVE  ON }
{ $WARN  XML_NO_PARM  ON }
{ $WARN  XML_NO_MATCHING_PARM  ON }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值