条件编译
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgConditionalCompilation
- 最后更新: 2019-10-05
条件编译允许使用"预处理器命令"来改变代码的生成方式。
'#define' 命令允许定义编译常量,即描述程序编译目标平台参数的常量。
这些常量使得可以执行条件编译,即根据编译期间定义的参数来修改程序的行为。
'#define' 命令还用于将程序的标识符替换为其他标识符,例如,在不修改整个程序的情况下测试同一函数的多个版本。
编译常量
需要明确区分使用预处理器 '#define' 指令定义的编译常量和使用 'const' 关键字定义的常量。
事实上,字面量常量不保留内存。这些是由编译器定义的立即值。
另一方面,'const' 仍然可以保留内存空间。例如,在处理字符串字面量时就是这种情况。
用预处理器 '#define' 指令声明的字面量常量将始终保持其值(前提是未被重新定义)。这些字面量常量没有类型,这在代码中可能非常令人烦恼且容易出错。
它们的使用将仅限于编译常量,而程序的所有其他常量将优先使用 'const' 关键字。
预处理器会自动设置许多内置常量。
这些是"内置定义"(请参阅其列表)。
条件编译
标识符和编译常量的定义被广泛用于执行所谓的条件编译。
条件编译包括根据编译常量的存在或值,将某些源代码部分替换为其他部分。
这可以通过条件编译指令实现。
其中最常见的可能是:
#ifdef symbol
' Conditionally included statements
#endif
如果标识符 symbol 是预处理器已知的,则 #ifdef(即"if defined")和 #endif 之间的文本将原样保留。否则,它将被删除(标识符可以仅使用之前介绍的 #define 命令声明)。
还有其他条件编译指令,如:
#ifndef (if not defined ...)(如果未定义...)#else/#elseif (otherwise ... / otherwise, if ...)(否则... / 否则,如果...)#if (if ...)(如果...)
#if 指令期望一个常量表达式作为参数(当且仅当该表达式为真时,后面的文本才会包含在文件中)。
编译指令的另一个常见应用是防止头文件被多次包含:
#ifndef AlreadyThere
#define AlreadyThere
' Text to include only once at most.
#endif
这可以防止由于多次调用 #include 而导致文本被多次包含。
事实上,在第一次调用时,AlreadyThere 不是预处理器已知的。因此,它被声明,文本被包含。
在任何后续调用中,AlreadyThere 已存在,文本不会被包含。
这种写法见于头文件中,通常我们不希望发生多次包含。
示例
使用内置定义 __FB_DEBUG__ 对递归函数进行调试的条件编译示例:
start GeSHi
Function recursiveFactorial (ByVal n As Integer) As Integer
If (n = 0) Then '' end condition
#if __FB_DEBUG__ <> 0
Print "end of recursion and result:";
#endif
Return 1
Else '' recursion loop
#if __FB_DEBUG__ <> 0
Print "multiply by: " & n
#endif
Return n * recursiveFactorial(n - 1) '' recursive call
End If
End Function
Print recursiveFactorial(5)
Sleepend GeSHi
不带 -g 选项编译后的输出:
120带 -g 选项编译后的输出:
multiply by: 5
multiply by: 4
multiply by: 3
multiply by: 2
multiply by: 1
end of recursion and result: 120参见
返回 目录