选择性编译

Selective compilation

我想知道在任何编程语言中是否有一种能力,我可以选择只编译特定部分的代码。请参阅下面的示例。

这是一段伪代码:

function foo() {

    if (isDebug) {
      checkSomethingForDebugging();
      print(some debug info);
    }

    toSomeFooThings();
}

此块用于调试目的,我想在生产中忽略它们(甚至是 if 语句)。

if (isDebug) {
  checkSomethingForDebugging();
  print(some debug info);
}

我能做的一件事就是注释掉这些行,

function foo() {

    //if (isDebug) {
    //  checkSomethingForDebugging();
    //  print(some debug info);
    //}

    toSomeFooThings();
}

但是如果我有成千上万个这样的地方怎么办?如果有一种方法(一个标志)可以让我选择编译或不编译代码的某个部分,那就太好了。就像一个debugging build。在任何编程语言中都有什么吗?我确实在网上搜索过,但运气不好。

好吧,这取决于您使用的编译器。例如,在 C 编程语言的 GCC 中,您有一整套可用于此的预处理器指令。

例如:

#ifdef DEBUG
// Your code here...
#endif /* DEBUG */

并且,当您编译调试版本时,您只需包含一个额外的头文件来定义 DEBUG 宏。不需要设置任何值,直接定义即可。

#define DEBUG

就是这样。

大多数语言没有这个,但您当然可以编写一个脚本来处理 build/deploy 管道中某处的源代码并删除仅调试部分。一种高级方法是正确解析源代码并删除适当的 if 块。对于 Python 这将很容易使用 ast 模块或只查找说 if is_debug: 的行然后观察缩进级别。对于其他语言,它可能更难。就预处理脚本而言,一种更简单的方法是使用定界注释:

// DEBUGONLY
checkSomethingForDebugging();
print(some debug info);
// ENDDEBUGONLY

在这种情况下,if 语句是可选的,具体取决于您想要做的事情。

有些语言(包括 C、C++ 和 C#)可以使用 #if#ifdef:

等预处理器指令来执行此操作
#if DEBUG
checkSomethingForDebugging();
print(some debug info);
#endif

编译代码时,如果未设置DEBUG符号,则两个指令之间的代码根本不会编译(甚至不必是有效代码)。

但更重要的是,你为什么要问?如果您担心性能,那么此类检查非常便宜(因为它们很容易预测)。如果检查写得正确(例如,如果 isDebug 是一个全局常量)并使用一个好的编译器编译,they can even be eliminated as dead code,这使得它们完全免费。