【问题标题】:C Preprocessor include directiveC 预处理器包含指令
【发布时间】:2020-10-26 13:09:45
【问题描述】:

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

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

#include <stdio.h> 

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

【问题讨论】:

    标签: c include c-preprocessor


    【解决方案1】:

    没有。相反:

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

    【讨论】:

      【解决方案2】:

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

      extern int a (int b);
      
      extern char * c (void);
      
      static inline int d (int e, int f) {
          ...
      }
      
      extern void * g (void * h);
      
      ...
      

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

      【讨论】:

        猜你喜欢
        • 2010-09-23
        • 2019-06-22
        • 2013-06-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多