delphi Integer overflow Delphi中预编译指令

  1. //The Hashing code was taken from David's Answer to make this a complete answer.
  2. {$IFOPT Q+}
  3. {$DEFINE OverflowChecksEnabled}
  4. {$Q-}
  5. {$ENDIF}
  6. function CombinedHash(const Values: array of Integer): Integer;
  7. var
  8. Value: Integer;
  9. begin
  10. Result := 17;
  11. for Value in Values do begin
  12. Result := Result*37 + Value;
  13. end;
  14. end;
  15. {$IFDEF OverflowChecksEnabled}
  16. {$Q+}
  17. {$ENDIF}

class function TSuperAvlEntry.Hash(const k: SOString): Cardinal;

var

h: cardinal;

i: Integer;

begin

h := 0;

{$Q-}

for i := 1 to Length(k) do

h := h*129 + ord(k[i]) + $9e370001;//这行

{$Q+}

Result := h;

end;

https://blog.csdn.net/shuaihj/article/details/6125868

Delphi7.0 预编译指令说明

A.1 使用编译设置对话框

编译器的编译指令是用于指定编译器对项目编译过程的动作和行为。可以通过[Project]->[Options]->

[Complier]选项页进行设置(快捷键:Crtl+Shift+F11),绝大部分的编译环境都可以通过这一对话框进行调

整,他包含了对代码、语法、调试信息等的设置。

1.代码设置(Code Generation)

Optimization: 是否优化代码。包括防止变量到CPU寄存器、合并分解表达式、生成中间变量等,其作用

域是局部的。

如果{$O+}或{$OPTIMIZATION ON},如下

var

I: Integer;

begin

I := 1; //不被编译,也就是说调试的时候,这行没有断点

I := 2;

end;

如果{$O-}或{$OPTIMIZATION OFF},如下

var

I: Integer;

begin

I := 1; //被编译,也就是说调试的时候,这行有断点

I := 2;

end;

缺省:{$O+}{$OPTIMIZATION ON}

Stack frames: Windows 堆栈帧。其作用域是局部的,他使编译器成为远端过程和函数生成特定的开头和

结尾代码。这个指令用于Windows 3.0的实模式,对所有Delphi应用程序他应该是关闭的,一些调试工具

需要此类信息。

如果{$W+}{$STACKFRAMES ON},强制每个过程或函数生成堆帧,查找错误时,编译器需要堆帧帮忙。

如果{$W-}{$STACKFRAMES OFF},Delphi 会只在需要时才产生堆帧。

缺省:{$W-}{$STACKFRAMES OFF}

注:谁知道 Delphi 会在什么时后才产生堆帧,老人家向大家请教了?

Pentium-safe FDIV: Pentium安全FDIV检查。此指令能够在Pentium处理器中指定编译器是否创建能够检

测和使用有缺陷的浮点除法指令的代码。

如果{$U+}{$SAFEDIVIDE ON}自动产生对 Pentium 芯片的 bug 检查代码。

如果{$U-}{$SAFEDIVIDE OFF}不产生对 Pentium 芯片的 bug 检查代码。

缺省:{$U-}{$SAFEDIVIDE OFF}

注:这个已经不再需要了。这批有 bug 的芯片,intel 公司已经基本回收掉了(老人家现在还保留一块,

值钱了!)。

2.运行期错误(Runtime Errors)

Range Checking: 范围检查。这个指令的作用范围是局部的,用于控制范围检验代码的生成。是否对

ShortString、有序类型和Array执行越界检查。打开后增加可执行文件大小、减慢速度,一般在调试阶段

使用

如果{$R+}或{$RANGECHECKS ON},如下

var

aInt: array[0..1] of Integer;

I: Integer;

begin

I := 2;

aInt[I] := 3; //运行时提示 "Range Checking error"

end;

如果{$R-}或{$RANGECHECKS OFF},如下

var

aInt: array[0..1] of Integer;

I: Integer;

begin

I := 2;

aInt[I] := 3; //运行时提示 "Access violation at address ?. Read of address ?."

end; //?=内存地址

缺省:{$R-}{$RANGECHECKS OFF}

I/O Checking: I/O检查。这个指令的作用域为局部,用来生成对一个文件的输入和输出过程和调用结果

进行检查的代码。一般应该使其功能打开。

如果{$I+}或{$IOCHECKS ON},EInOutError检查,一旦发生I/O错误时,将会触发一个EInOutError的例外

如果{$I-}或{$IOCHECKS OFF}程序执行时发生过I/O操作错误(例如检测文件是否存在函数),程序设定师

必须自行检查IOResult这个公用变量的值,如果是零,表示没有错误。IOResult函数在System.pas

缺省:{$I+}{$IOCHECKS ON}

Overflos Checking: 溢出检查。其作用是生成对算术溢出检查的代码。打开后增加可执行文件大小、减

慢速度,一般在调试阶段使用

如果{$Q+}或{$OVERFLOWCHECKS ON},如下

var

B: Byte;

begin

B := 255; //运行时提示 "Integer Overflos."

Inc(B);

end;

如果{$Q-}或{$OVERFLOWCHECKS OFF},如下

var

B: Byte;

begin

B := 255; //运行时 B := 0;

Inc(B);

ShowMessage(IntToStr(B));

end;

缺省:{$Q-}{$OVERFLOWCHECKS OFF}


在命令行下输入:dcc32 /? >1.txt可以把编译的开关指令弄到文本文件中,内容如下:

Borland Delphi Version 15.0

Copyright (c) 1983,2002 Borland Software Corporation

Syntax: dcc32 [options] filename [options]

语法:dcc32 选项 文件名 选项

-A<unit>=<alias> = Set unit alias

-A <单元>=<别名> 设置单元别名

-B = Build all units

编译所有单元

-CC = Console target

控制台目标

-CG = GUI target

图形用户接口目标

-O<paths> = Object directories

-O <路径> 对象目录

-D<syms> = Define conditionals

-P = look for 8.3 file names also

以8.3文件名格式查看

-E<path> = EXE output directory

exe文件的输出目录

-Q = Quiet compile

静态编译(俺猜想估计是不乱七八糟的提示俺代码错误的编译吧。哈哈)

-F<offset> = Find error

找错?(现在俺的级别不用找错误都很多啊

-R<paths> = Resource directories

资源文件目录

-GD = Detailed map file

详细的映射?(地图)文件

-U<paths> = Unit directories

单元目录

-GP = Map file with publics

公开的地图文件

-V = Debug information in EXE

exe文件里的调试信息

-GS = Map file with segments

-VR = Generate remote debug (RSM)

生成远程调试

-H = Output hint messages

输出隐藏的消息

-W = Output warning messages

输出警告信息

-I<paths> = Include directories

包含目录

-Z = Output 'never build' DCPs

?不压缩的输出?

-J = Generate .obj file

生成.obj文件

-$<dir> = Compiler directive

编译器目录

-JP = Generate C++ .obj file

生成C++格式的.obj文件

--help = Show this help screen

在屏幕上显示帮助

-K<addr> = Set image base addr

--version = Show name and version

显示名称和版本

-LU<package> = Use package

使用包文件

-M = Make modified units

重建单元

-N<path> = DCU output directory

DCU输出目录

上述为dcc32程序的参数,下面是编译器开关

Compiler switches: -$<letter><state> (defaults are shown below)

编译器开关:-$<字母><状态>(下面显示的是默认值)

A8 Aligned record fields

The $A directive controls alignment of fields in Delphi record types and class structures.

红色部分是帮助文件里的。

好像是说指令控制器在delphi记录类型和类结构里对器的字段?

P+ Open string params

B- Full boolean Evaluation Q- Integer overflow checking

C+ Evaluate assertions at runtime R- Range checking

D+ Debug information T- Typed @ operator

G+ Use imported data referencesU- Pentium(tm)-safe divide

H+ Use long strings by default V+ Strict var-strings

I+ I/O checkingW- Generate stack frames

J- Writeable structured consts X+ Extended syntax

L+ Local debug symbols Y+ Symbol reference info

M- Runtime type info Z1 Minimum size of enum types

O+ Optimization

https://www.cnblogs.com/findumars/p/8207341.html

本文转自 http://www.cnblogs.com/JackSun/archive/2010/12/20/1911250.html

《Delphi下深入Windows核心编程》(附录A Delphi编译指令说明)

Delphi快速高小的编译器主要来自Object PASCAL的严谨,使用Delphi随时都在与编译器交流,大部分情况下不需要干涉编译器的运行,但是有

时也需要对编译器进行必要的设置。

**********************************************************************************************

A.1 使用编译设置对话框

编译器的编译指令是用于指定编译器对项目编译过程的动作和行为。可以通过[Project]->[Options]->[Complier]选项页进行设置,绝大部分

的编译环境都可以通过这一对话框进行调整,他包含了对代码、语法、调试信息等的设置。

1.代码设置(Code Generation)

Optimization: 代码优化开关

Aligned record fields: 字对齐数据。这个编译指令能够在变量和类型化常量的字节对齐和字对齐之间进行切换,其作用是全局的。

Stack frames: Windows 堆栈帧。其作用域是局部的,他使编译器成为远端过程和函数生成特定的开头和结尾代码。这个指令用于Windows 3.0

的实模式,对所有Delphi应用程序他应该是关闭的。

Pentium-safe FDIV: Pentium安全FDIV检查。此指令能够在Pentium处理器中指定编译器是否创建能够检测和使用有缺陷的浮点除法指令的代码

2.运行期错误(Runtime Errors)

Range Checking: 范围检查。这个指令的作用范围是局部的,用于控制范围检验代码的生成。

I/O Checking: I/O检查。这个指令的作用域为局部,用来生成对一个文件的输入和输出过程和调用结果进行检查的代码。一般应该使其功能打

开。

Overflos Checking: 溢出检查。其作用是生成对算术溢出检查的代码。

3.语法设置(Syntax Optings)

Strict Var- strings: 静态变量串开关。用来控制对以变量参数形式传递的串的类型检查。

Comlete Boolean Eval: 完全布尔表达量判定。用于执行强制的完整表达式判定。完全布尔量判定,有可能导致系统崩溃,所以一般不使用他

Extended Syntax: 扩展语法开关。他能允许或禁止Delphi的扩展语法。

Typed @ Operator: 类型化的@运算符检查。应用于局部的变量引用上,控制@运算符返回的指针值类型。

Open Parameters: 开放参数开关。用于控制使用String关键字声明的变量参数。开放参数允许将大小不一的串变量传递到同一个过程或函数中

,一般在汇编中会使用到。

Huge Strings: 字符串类型开关。用于控制Ansistring和Shortstring类型的切换。当打开时符合Ansistring,关闭时符合Shortstring。

Assignable Typed Constants: 可分配类型常量。用于向下与Delphi 1.0兼容。

4.调试(Debugging)

Debug Information: 调试信息开关。用于设置是否把调试信息写入以编译的单元文件(.dcu)。

Local Symbols: 局部符号开关。允许或禁止局部符号信息的创建。

Reference Info/Definitions Only: 符号信息开关。用于允许或禁止由Delohi的对象浏览器使用的符号引用信息的生成。

Assertions: 用于控制局部代码的属性。

Use Debug DCUs: 使用或禁止VCL的DCU文件调试。

5.信息(Messages)

Show Hints: 显示暗示。

Show Warnings: 显示警告。

**********************************************************************************************

A.2 使用编译指令

除了使用编译设置对话框对编译器进行设置外,还可以通过编译指令来对编译器进行设置。

对于局部的编译器设置,只有使用编译指令来完成。

对于开关编译指令,通过在编译指令后加入指示开关状态的加号和减号来控制编译器。例如:

{$B+} : 打开完全布尔量检查。

{$Q-} : 关闭溢出检查。

通常,编译指令的作用域是在编译指令后的代码部分,而对于全程的编译指令应该防在单元接口部分的开头。

编译设置对话框的设置都有与之对应的编译指令用于在代码中对编译器进行设置,如下表所示。

设置项 编译指令

Optimizations {$O}

Aligned record fields {$A}

Stack frames {$W}

Pentium-safe FDIV {$U}

Range Checking {$R}

I/O Checking {$I}

Overflow Checking {$Q}

Strict Var-strings {$V}

Comlete Boolean Eval {$B}

Extended Syntax {$X}

Typed @ Operator {$T}

Open Parameters {$P}

Huge Strings {$H}

Assertions typed constants {$J}

Debug information {$D}

Local sysnbols {$L}

在这些编译指令以外还有一些非常有用的编译指令。

$R Filename : 这个编译指令是最为常用的编译指令,他是资源文件编译指令,用于指定连接到执行文件和库的资源文件,例如在工程文件

(.dpr)中会有{$R *.RES}的编译指令,表明把后缀为 .RES的与工程文件同名的资源文件连接入执行文件,也可以指定一个资源文件,资源文件

的使用对于编写Windows程序来说是很重要的基础。

$I Filename :这个编译指令功能类似于C语言的#Include , 用于指定编译时包括的文件。

**********************************************************************************************

A.3 使用条件编译指令

条件编译指令是非常重要的编译指令,他控制着在不同条件下(例如,不同的操作系统)产生不同的代码。条件编译指令是包含在

注释括号之内的,如下表所示。

条件编译指令 含义

$DEFINE 用于定义一个条件符号,一旦定义,条件符号就为真

$ELSE 与$IFDEF配合使用,如果$IFDEF条件为假,则只对源文件$ELSE后一小部分进行编译

$ENDIF 结束一个以$IF开始的条件段

$IFDEF 对条件符号进行判断,为真则编译源文件

$IFNDEF 对条件符号进行判断,为假则编译源文件

$IFOPT 根据编译开关状态,对源文件编译

$UNDEF 撤消以前的条件符号定义

这些条件编译指令是非常有用的。例如,可以通过开关的状态来控制编译:

{IFOPT R+}

showmessage('Compiled with range-checking');

{$ENDIF}

也可以通过定义条件符号来控制编译:

{$Define s}

……

{$ifdef s}

showmessage('yes');

{$else}

showmessage('no');

{$endif}

他的编译结果是显示'yes',但是如果省去{$Define s}则显示'no'。

在Delphi中已经预定义了一些关键的条件符号,如下表所示。

条件符号 含义

VERxx 编译器版本,XX表示版本,例如:Delphi 1.0 的编译器版本为80、Delphi 5.0 的编译器版本为130

WIN32 是否WIN32的运行环境(Windows 95.98/NT/2000)

CPU386 是否Intel386以上的处理器

CONSOLE 是否控制台程序

Delphi的编译器指令除了以上的指令外还有一些,不过最为常用的指令已经全部介绍完了。对于普通的程序,Delphi是不需要编程者去添加编

译器指令的,Delphi已经自动完成,但是要得到高品质的应用程序或者有特殊的要求的程序就必须熟悉Delphi的编译指令。Delphi不仅有最快

的编译器而且编译器的功能也非常强大。

**********************************************************************************************

简单例子:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

procedure FormCreate(Sender: TObject);

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

FCaption: string;

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

//用到文件 VersionDefinition.inc

{$I VersionDefinition.inc} 或 {$DEFINE AAA} // 定义行

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

FCaption := 'Other';

{$IFDEF AAA}

FCaption := 'AAA';

{$ENDIF}

{$IFDEF BBB}

FCaption := 'BBB';

{$ENDIF}

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

Caption := FCaption;

end;

end.

**************************

文件VersionDefinition.inc内容

//////////////////////////

{$DEFINE AAA}

{..$DEFINE BBB}

-------------------------------------------

1.编译后运行,按下Button,则看到窗体标题栏显示“AAA”。程序编译了FCaption := ’AAA’的语句。

2.改变定义行的程序段:

当改为{$DEFINE BBB}时,再次编译运行,则看到窗体标题栏显示“BBB”。程序编译了FCaption := ’BBB’的语句。当取消定义行或改为{$DEFINE NOTHING}或其他名称时,再次编译运行,则看到窗体标题栏显示“Other”。程序只编译了FCaption := ’Other’的语句。

http://blog.csdn.net/hksoobe/article/details/31252729

本文转自 http://www.cnblogs.com/JackSun/archive/2010/12/20/1911250.html

《Delphi下深入Windows核心编程》(附录A Delphi编译指令说明)

Delphi快速高小的编译器主要来自Object PASCAL的严谨,使用Delphi随时都在与编译器交流,大部分情况下不需要干涉编译器的运行,但是有

时也需要对编译器进行必要的设置。

**********************************************************************************************

A.1 使用编译设置对话框

编译器的编译指令是用于指定编译器对项目编译过程的动作和行为。可以通过[Project]->[Options]->[Complier]选项页进行设置,绝大部分

的编译环境都可以通过这一对话框进行调整,他包含了对代码、语法、调试信息等的设置。

1.代码设置(Code Generation)

Optimization: 代码优化开关

Aligned record fields: 字对齐数据。这个编译指令能够在变量和类型化常量的字节对齐和字对齐之间进行切换,其作用是全局的。

Stack frames: Windows 堆栈帧。其作用域是局部的,他使编译器成为远端过程和函数生成特定的开头和结尾代码。这个指令用于Windows 3.0

的实模式,对所有Delphi应用程序他应该是关闭的。

Pentium-safe FDIV: Pentium安全FDIV检查。此指令能够在Pentium处理器中指定编译器是否创建能够检测和使用有缺陷的浮点除法指令的代码

2.运行期错误(Runtime Errors)

Range Checking: 范围检查。这个指令的作用范围是局部的,用于控制范围检验代码的生成。

I/O Checking: I/O检查。这个指令的作用域为局部,用来生成对一个文件的输入和输出过程和调用结果进行检查的代码。一般应该使其功能打

开。

Overflos Checking: 溢出检查。其作用是生成对算术溢出检查的代码。

3.语法设置(Syntax Optings)

Strict Var- strings: 静态变量串开关。用来控制对以变量参数形式传递的串的类型检查。

Comlete Boolean Eval: 完全布尔表达量判定。用于执行强制的完整表达式判定。完全布尔量判定,有可能导致系统崩溃,所以一般不使用他

Extended Syntax: 扩展语法开关。他能允许或禁止Delphi的扩展语法。

Typed @ Operator: 类型化的@运算符检查。应用于局部的变量引用上,控制@运算符返回的指针值类型。

Open Parameters: 开放参数开关。用于控制使用String关键字声明的变量参数。开放参数允许将大小不一的串变量传递到同一个过程或函数中

,一般在汇编中会使用到。

Huge Strings: 字符串类型开关。用于控制Ansistring和Shortstring类型的切换。当打开时符合Ansistring,关闭时符合Shortstring。

Assignable Typed Constants: 可分配类型常量。用于向下与Delphi 1.0兼容。

4.调试(Debugging)

Debug Information: 调试信息开关。用于设置是否把调试信息写入以编译的单元文件(.dcu)。

Local Symbols: 局部符号开关。允许或禁止局部符号信息的创建。

Reference Info/Definitions Only: 符号信息开关。用于允许或禁止由Delohi的对象浏览器使用的符号引用信息的生成。

Assertions: 用于控制局部代码的属性。

Use Debug DCUs: 使用或禁止VCL的DCU文件调试。

5.信息(Messages)

Show Hints: 显示暗示。

Show Warnings: 显示警告。

**********************************************************************************************

A.2 使用编译指令

除了使用编译设置对话框对编译器进行设置外,还可以通过编译指令来对编译器进行设置。

对于局部的编译器设置,只有使用编译指令来完成。

对于开关编译指令,通过在编译指令后加入指示开关状态的加号和减号来控制编译器。例如:

{$B+} : 打开完全布尔量检查。

{$Q-} : 关闭溢出检查。

通常,编译指令的作用域是在编译指令后的代码部分,而对于全程的编译指令应该防在单元接口部分的开头。

编译设置对话框的设置都有与之对应的编译指令用于在代码中对编译器进行设置,如下表所示。

设置项 编译指令

Optimizations {$O}

Aligned record fields {$A}

Stack frames {$W}

Pentium-safe FDIV {$U}

Range Checking {$R}

I/O Checking {$I}

Overflow Checking {$Q}

Strict Var-strings {$V}

Comlete Boolean Eval {$B}

Extended Syntax {$X}

Typed @ Operator {$T}

Open Parameters {$P}

Huge Strings {$H}

Assertions typed constants {$J}

Debug information {$D}

Local sysnbols {$L}

在这些编译指令以外还有一些非常有用的编译指令。

$R Filename : 这个编译指令是最为常用的编译指令,他是资源文件编译指令,用于指定连接到执行文件和库的资源文件,例如在工程文件

(.dpr)中会有{$R *.RES}的编译指令,表明把后缀为 .RES的与工程文件同名的资源文件连接入执行文件,也可以指定一个资源文件,资源文件

的使用对于编写Windows程序来说是很重要的基础。

$I Filename :这个编译指令功能类似于C语言的#Include , 用于指定编译时包括的文件。

**********************************************************************************************

A.3 使用条件编译指令

条件编译指令是非常重要的编译指令,他控制着在不同条件下(例如,不同的操作系统)产生不同的代码。条件编译指令是包含在

注释括号之内的,如下表所示。

条件编译指令 含义

$DEFINE 用于定义一个条件符号,一旦定义,条件符号就为真

$ELSE 与$IFDEF配合使用,如果$IFDEF条件为假,则只对源文件$ELSE后一小部分进行编译

$ENDIF 结束一个以$IF开始的条件段

$IFDEF 对条件符号进行判断,为真则编译源文件

$IFNDEF 对条件符号进行判断,为假则编译源文件

$IFOPT 根据编译开关状态,对源文件编译

$UNDEF 撤消以前的条件符号定义

这些条件编译指令是非常有用的。例如,可以通过开关的状态来控制编译:

{IFOPT R+}

showmessage('Compiled with range-checking');

{$ENDIF}

也可以通过定义条件符号来控制编译:

{$Define s}

……

{$ifdef s}

showmessage('yes');

{$else}

showmessage('no');

{$endif}

他的编译结果是显示'yes',但是如果省去{$Define s}则显示'no'。

在Delphi中已经预定义了一些关键的条件符号,如下表所示。

条件符号 含义

VERxx 编译器版本,XX表示版本,例如:Delphi 1.0 的编译器版本为80、Delphi 5.0 的编译器版本为130

WIN32 是否WIN32的运行环境(Windows 95.98/NT/2000)

CPU386 是否Intel386以上的处理器

CONSOLE 是否控制台程序

Delphi的编译器指令除了以上的指令外还有一些,不过最为常用的指令已经全部介绍完了。对于普通的程序,Delphi是不需要编程者去添加编

译器指令的,Delphi已经自动完成,但是要得到高品质的应用程序或者有特殊的要求的程序就必须熟悉Delphi的编译指令。Delphi不仅有最快

的编译器而且编译器的功能也非常强大。

**********************************************************************************************

简单例子:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

procedure FormCreate(Sender: TObject);

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

FCaption: string;

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

//用到文件 VersionDefinition.inc

{$I VersionDefinition.inc} 或 {$DEFINE AAA} // 定义行

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

FCaption := 'Other';

{$IFDEF AAA}

FCaption := 'AAA';

{$ENDIF}

{$IFDEF BBB}

FCaption := 'BBB';

{$ENDIF}

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

Caption := FCaption;

end;

end.

**************************

文件VersionDefinition.inc内容

//////////////////////////

{$DEFINE AAA}

{..$DEFINE BBB}

-------------------------------------------

1.编译后运行,按下Button,则看到窗体标题栏显示“AAA”。程序编译了FCaption := ’AAA’的语句。

2.改变定义行的程序段:

当改为{$DEFINE BBB}时,再次编译运行,则看到窗体标题栏显示“BBB”。程序编译了FCaption := ’BBB’的语句。当取消定义行或改为{$DEFINE NOTHING}或其他名称时,再次编译运行,则看到窗体标题栏显示“Other”。程序只编译了FCaption := ’Other’的语句。

http://blog.csdn.net/hksoobe/article/details/31252729