如果不包含标头,将使用getenv的哪种实现?

时间:2019-07-15 04:40:57

标签: c

出于学习目的,我正在开发一个简单的程序,并且看到以下行为:

如果我尝试使用getenv读取环境变量,它将按预期工作:

/usr/bin/git

如果不包含stdlib.h,则会收到预期的警告:

#include <stdio.h>
#include <stdlib.h> 

int main() {
    printf("PATH is %s", getenv("PATH"));
    return 0;
}

程序仍在编译。使用标头运行该程序会按预期运行,不包含标头的程序会出现段错误。

如果我检查了两个程序的反汇编,就会发现有一个对getenv @ PLT的调用

env.c:7:26: warning: implicit declaration of function ‘getenv’; did you mean ‘getline’? [-Wimplicit-function-declaration]

当我输出两个程序的反汇编时(c源代码中唯一的区别是标头包括),我看到的唯一区别是当我们包含标头时,有一条指令将%eax设置为0打电话给getenv。

call    getenv@PLT

如果我在不包含标头的情况下进入gdb程序,它将跳入getenv并在c运行时中运行大量代码。

我想知道为什么不包含标头会导致这种行为的确切原因是什么? c为什么要让它编译?

一些信息: gcc版本7.4.0(Ubuntu 7.4.0-1ubuntu1〜18.04.1) 我正在这样编译: gcc -O0 -S env.c

1 个答案:

答案 0 :(得分:2)

在C语言中,如果忘记了包含头文件,则getenv()函数将被解释为int getenv(...)。如果包含头文件,则getenv()函数将被解释为char* getenv(const char*)。由于printf()的实现,您情况的唯一区别是返回值的大小。如果为sizeof(int) == sizeof(char*),则表示没有问题(对于32位程序,会发生这种情况)。如果为sizeof(int) != sizeof(char*),则会出现错误(对于64位程序,会发生这种情况)。这在注释#5

中有解释