C预处理器包含指令

时间:2020-10-26 13:09:45

标签: c include c-preprocessor

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

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

#include <stdio.h> 

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

2 个答案:

答案 0 :(得分:3)

不。相反:

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

#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的定义。

答案 1 :(得分:1)

正如其他人所说,#include将逐字粘贴您要定位的整个文件。但是,您通常会包含标题,这些标题通常看起来像

extern int a (int b);

extern char * c (void);

static inline int d (int e, int f) {
    ...
}

extern void * g (void * h);

...

上面的代码恰好占用零内存(除非您使用inline函数之一开始 ),因为它完全由编译器的指令组成,而没有其他内容。