为什么在代码块中编写include语句有时是有效的?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (21)

我来自python背景,其中以下内容有效:

def f():
    #include someLibrary
    someLibrary.libraryFunction()

所以,当我需要调试C代码时,我在函数中写道:

void f(int param)
{
     int status;
     /* other code */
     #include <stdio.h>
     printf("status: %d", status);
     /* more code */
}

它按照我的预期编译和工作。后来有人向我指出,这不应该编译,因为C预处理器字面上取代了#include~ statement with the contents ofstdio.h`。那么为什么这个有效的代码呢?

提问于
用户回答回答于

是的,C和Python在这方面有很大的不同。

#include在编译之前,预处理器将指令替换为包含文件的内容是正确的。

是否导致编译错误完全取决于所包含文件的内容。标准头文件stdio.h不包含任何可执行语句 - 它们只包含typdef,函数声明,其他宏等内容。它们通常还有某种#include防护措施,可防止每个翻译单元多次加载(是,如果你#include是一个包含的文件,stdio.h然后#include <stdio.h>直接在同一个源文件中,stdio.h只会加载一次内容)。

从理论上讲stdio.h在代码中包含随机点是没有问题的,但它可能会导致问题。在这种情况下,所有stdio.h的内容只有身体可见f- 如果只f需要使用任何东西stdio.h,这不是问题,但否则会导致头痛。

标准头文件最好包含在源文件的开头。

用户回答回答于

有人向我指出,这不应该编译,因为C预处理器字面上将#include语句替换为stdio.h的内容。

这个逻辑没有意义。仅仅因为预处理器从stdio.h文件中插入文本并不意味着它不应该编译。如果该文件中没有任何内容会导致编译错误,那么它将编译得很好。

此外,标题通常包含多个包含保护。因此,如果它们之前已被包括在内,那么任何进一步包含它的尝试都没有效果。在这种情况下,如果<stdio.h>先前已经包含在文件中(直接或间接),则#include无效。

话虽如此,不要这样做。在C中,在函数范围内不应包含标准头文件。

扫码关注云+社区

领取腾讯云代金券