AMXXPawn编译器指令#pragma

#pragma指令使用方法:

#pragma 额外指令名称 额外信息

该指令能指示编译器对特定代码进行非标准化的处理,改变编译方式.

例如改变编译器警告等级,优化等级,语句必须以分号结尾,切换字符串字面量的解析方式.

不同版本的编译器,可能会有不同的额外指令.具体需要查阅编译器源码(去AMXX官网下载).

#pragma align

#pragma align

使用对齐指令将下一个声明与偏移集对齐.

当参数在8,16,32字节的边界上时,一些本机函数可以更好地使用通过引用传递的参数.对齐要求取决于主机应用程序.

#pragma align放在全局变量或静态变量的声明前面,可以使用编译器选项将该变量与边界集对齐.

这个#pragma只对齐紧跟在#pragma后面的变量.后续变量的对齐方式取决于其前面变量的大小和对齐方式.

例如,如果一个由2个单元格组成的全局数组变量在16字节的边界上对齐,而一个单元格为4字节,则下一个全局变量位于8字节之外.

#pragma align行放在函数的声明前面,将使该函数的栈框架与前面指定的边界对齐,结果是第一个栈变量与该边界对齐.

后续变量的对齐取决于其前面变量的大小和对齐方式.在实践中,要对齐栈变量,必须对齐函数的栈框架,并在任何其他变量之前声明该变量.

pawn-lang.pdf原文:

Aligns the next declaration to the offset set with the alignment compiler option.

Some (native) functions may perform better with parameters that are passed by reference when these are on boundaries of 8, 16, or even 32 bytes.

Alignment requirements are dependent of the host applications.

Putting the #pragma align line in front of a declaration of a global or a static variable aligns this variable to the boundary set with the compiler option.

This #pragma aligns only the variable that immediately follows the #pragma.

The alignment of subsequent variables depends on the size and alignment of the variables that precede it. For example,

if a global array variable of 2 cells is aligned on a 16-byte boundary and a cell is 4 bytes,

the next global variable is located 8 bytes further.

Putting the #pragma align line in front of a declaration of a function will align the stack frame of that function to the boundary specified earlier,

with the result that the first local, non-“static”, variable is aligned to that boundary.

The alignment of subsequent variables depends on the size and alignment of the variables that precede it.

In practice, to align a local non-static variable, you must align the function’s stack frame and declare that variable before any other variables.

#pragma amxlimit

#pragma amxlimit 常量表达式

设置插件运行时最多能占用多少内存空间(字节数).

相关信息可在编译报告中查看.

#pragma codepage

此指令只会导致报错,因为编译器源码中未能正确读取并使用该文件.

#pragma codepage #pragma codepage 文件名 #pragma codepage "文件名"

若填写文件名(字节数不得超过11),从下一行开始,根据文件内的编码映射,翻译所有字符串字面量.

编译器会在以下地址读取代码页文件:

编译器目录/codepage/文件名

文件名可以省略cp前缀和.txt后缀.也可以完整填写其它前缀或后缀.

文件内容格式:

键值 UNICODE

若不填写文件名,从下一行开始,不替换字符串字面量内的编码数值.

更多详情请查阅AMX Mod X源码中compiler\libpc300\sci18n.c文件内的SC_FUNC int cp_set(const char *name)函数.

#pragma compress

#pragma compress 常量表达式

若常量表达式非0,则对生成的插件进行压缩.以减小插件的文件大小.这种压缩有助于保护代码不被轻易反编译​.

默认值取决于解析器配置(也许还有用户设置).某些脚本源码在压缩模式下有可能无法被编译,可用该指令覆盖默认设定进行编译.

#pragma ctrlchar

#pragma ctrlchar #pragma ctrlchar 单值字面量

从下一行开始,使用单值字面量所指的字符作为转义序列的前缀字符.

示例:

const gOldLineFeed = '^n'; // 默认情况下,需要用 ^ 乘方字符作为前缀 #pragma ctrlchar '\' // 设定使用 \ 反斜杠作为转义序列的前缀字符 const gNewLineFeed = '\n'; // 新的写法 #pragma ctrlchar // 恢复默认

#pragma deprecated

#pragma deprecated #pragma deprecated 警告文本

弃用接下来被声明的第一个函数.如果定义或引用了它,编译时将在定义和所有引用位置触发警告.

#pragma dynamic

#pragma dynamic 常量表达式

设定脚本编译后拥有多大的栈空间.以cell为单位,每个cell为4字节.

若因为执行深层次递归导致栈溢出,可以用这个指令扩容.函数产生的参数和变量需要用到这些空间.

#pragma library/reqlib/reqclass/loadlib/explib/expclass/defclasslib

// 设定插件需要的"库",若"库"所指插件或模块未加载,则自动加载,失败则禁用当前插件. #pragma library 字符串字面量含有字母,数字,@,-的字段 // 设定插件需要的"库",若"库"所指插件或模块未加载,则禁用当前插件. #pragma reqlib 字符串字面量含有字母,数字,@或-的字段 // 设定插件需要的"库类",若"库类"所指模块未加载,则禁用当前插件. #pragma reqclass 字符串字面量含有字母,数字,@或-的字段 // 设定要尝试加载的"库"或"库类". #pragma loadlib 字符串字面量含有字母,数字,@或-的字段 // 设定2个被空格隔开,要尝试加载的"库",第1个失败才会尝试第2个. #pragma explib 字符串字面量2个含有字母,数字,@或-的字段 // 设定被空格隔开,要加载的"库类"和"库","库类"加载失败才会尝试加载"库". #pragma expclass 字符串字面量2个含有字母,数字,@或-的字段 // 设定被空格隔开,要加载的"库类"和"库","库类"加载失败才会尝试加载"库".但这个指令会等待所有"库"与"库类"相关期望都检查完毕后才进行检查. #pragma defclasslib 字符串字面量2个含有字母,数字,@或-的字段

注1:"库类"这个名称暗示了一个类可以含有多个库.

注2:插件可以用amxmodx.inc文件提供的register_library函数将自己转变为"库",但似乎不能设定所属"库类".

注3:这些内容不一定准确.详情查阅:https://wiki.alliedmods.net/AMX_Mod_X_1.75_Scripting_Changes

#pragma pack

#pragma pack 常量表达式

若常量表达式的值非0,从下一行开始交换压缩字符串和普通字符串字面量的书写格式.

正常情况下,压缩字符串字面量用!""包裹文本,而普通字符串字面量用""包裹文本.

#pragma rational

#pragma rational 类标签名称 #pragma rational 类标签名称 (精度)

启用浮点数支持,使脚本允许使用浮点数字面量(还需为该标签重载相关运算符,才能实现正确的浮点数运算).

类标签名称必须符合标识符命名规则.定义浮点类型数值的标签名称.

(精度)可省略,表示小数点后无限精度(实际上有限).

精度含有严重的设计错误,会产生各种bug.不要使用.

精度只能填1至8中的一个字,9虽然不报错但是会导致浮点数值错误.

一旦设定精度(1~8),浮点数值会放大10^精度倍得到定点整数(如精度为2情况下,1.23e1变为1230).若浮点数字面量包含负的非零指数(如e-3),则变为0.

该指令已经被float.inc文件所使用.只要引用float.incamxmodx.inc即可使用Float:标签作为浮点数标签.

除非你觉得Float:标签是大写开头很碍眼,想用自己写的模块替换它,否则应该不需要用到这个指令.

该指令不能重复使用.

#pragma semicolon

#pragma semicolon 常量表达式

若常量表达式的值非0,则不允许省略表达式语句结尾的 ; 分号.编译器指令所使用的表达式除外.

#pragma tabsize

#pragma tabsize 常量表达式

若常量表达式的值大于0,从下一行开始,该值被用于设定制表符能表示的最大空格数.

当上下两行的行数空格数不一致,就会触发编译器警告"缩进丢失".

某些文本编辑器比较有个性,不愿意把制表符画成8个空格的宽度,这种情况下可以用该指令重新对齐上下两行文本.

#pragma unused

#pragma unused 标记,常量,变量,或函数名称

若该指令在指定标识符的作用域内,让编译器不要警告该标识符未被使用.

#pragma showstackusageinfo

#pragma showstackusageinfo

该指令让编译器打印插件可用栈内存时,在末端加上栈的实际单元数量和内存数.