C 如果不包含头,则使用什么getenv实现?
我正在为学习目的编写一个简单的程序,我看到以下行为: 如果我尝试使用getenv读取环境变量,它将按预期工作:C 如果不包含头,则使用什么getenv实现?,c,C,我正在为学习目的编写一个简单的程序,我看到以下行为: 如果我尝试使用getenv读取环境变量,它将按预期工作: #include <stdio.h> #include <stdlib.h> int main() { printf("PATH is %s", getenv("PATH")); return 0; } 该程序仍在编译。如果使用标头运行程序,则不包含标头的程序会出现seg错误 如果我检查两个程序的反汇编,我会看到调用getenv@PLT c
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("PATH is %s", getenv("PATH"));
return 0;
}
该程序仍在编译。如果使用标头运行程序,则不包含标头的程序会出现seg错误
如果我检查两个程序的反汇编,我会看到调用getenv@PLT
call getenv@PLT
当我输出两个程序的反汇编时(c源代码中唯一的区别是头include),我看到的唯一区别是,当我们包含头时,有一条指令在调用getenv之前将%eax设置为0
movl $0, %eax
如果我在gdb中单步执行没有包含头的程序,它会跳转到getenv,并在c运行时中运行大量代码
我想知道为什么不在这里包含标题会导致这种行为的确切原因是什么?为什么c让它编译
一些信息:
gcc版本7.4.0(Ubuntu 7.4.0-1ubuntu1~18.04.1)
我是这样编译的:
在c语言中,如果忘记包含头文件,
getenv()
函数将被解释为int-getenv(…)
。如果包含头文件,getenv()
函数将被解释为char*getenv(const char*)
。由于实现了printf()
,所以在您的情况下唯一的区别就是返回值的大小。如果sizeof(int)==sizeof(char*)
,则没有问题(32位程序会出现这种情况)。如果sizeof(int)!=sizeof(char*)
,您会得到一个错误(64位程序会发生这种情况)。注释#5Trygcc-Wall-Wextra-pedantic
对此进行了解释。相关说明:它假设函数返回一个int
,并错误解释结果。不要这样做。为什么不在这里发布生成的汇编程序代码呢?如果编译的是64位,那是因为int
和指针大小不同,并且返回指针的未声明的getenv
被视为返回int
。但即使在这种情况下,汇编代码中也应该有其他区别,而不仅仅是将eax设置为零;调用printf
之前,在堆栈上推送的参数应该有所不同。您不会总是在64位上出错,这会使这一错误更加隐蔽。我同意您的看法
movl $0, %eax