首页 > 解决方案 > C 预处理器包含指令

问题描述

当我包含另一个源(即stdio.h)时,预处理器是否足够聪明,只包含我在代码中使用的函数?

示例:假设这个小程序,很容易只包含我正在使用的内容,以及 printf 函数使用的内容,递归地包括它们,但是更大的程序呢?

#include <stdio.h> 

int main(void) {
   printf("Hello World\n"); 
   return 0;
}

标签: cincludec-preprocessor

解决方案


不,相反:

#include执行文本替换:它打开文件并将其所有内容1复制到您的主 C 文件中。在此过程中,它执行包含文件中的所有预处理器指令。除其他外,这意味着它将递归地包含所有#included 在标头中的文件。

#include不知道也不关心您最终使用的是包含文件的哪一部分。


1如前所述,预处理器指令在包含的文件中执行。这可以修改包含的内容。例如,假设以下头文件header.h

#ifndef HEADER_H
#define HEADER_H

#ifdef NDEBUG
#  define LOG(...) ((void) 0)
#else
#  define LOG(...) log_message(__FILE__, __LINE__, __VA_ARGS__)

inline void log_message(const char* filename, int line, ...) {
    // Logging code omitted for brevity.
}
#endif

// other stuff

#endif

现在,如果您的main.c文件如下所示:

#define NDEBUG
#include "header.h"

int main(void) {
    // …
    LOG("hello");
}

…然后,在预处理之后,你的main.c文件看起来像这样(我省略了一些不相关的东西):

# 1 "main.c"

# 1 "./header.h" 1




# 13 "./header.h"

// other stuff


# 3 "main.c" 2

int main(void) {
    // …
    ((void) 0);
}

……换句话说,只包括header.h了对应#ifdef NDEBUG的部分,而不包括#else子句中的部分。如果我们在header.h没有定义的情况下NDEBUG包含,那么包含的标头代码将包含 的定义log_message


推荐阅读