查看Linux C标准库的来源,我发现函数fopen
的来源使用了open
,人们可能会认为 open
系统调用,但它不是,而是在标准库源中定义为
# define open(Name, Flags, Prot) __open (Name, Flags, Prot)
确实,我检查过如果我注释掉上面的行并重新编译标准库,那么生成的fopen
就可以正常工作并调用系统调用open
。
我可以找到open
的大量文档,但__open
没有。
然后我很困惑......什么是__open
,它在哪里记录,为什么fopen
调用它而不是open
?
答案 0 :(得分:0)
这是内部编译时重定向。 POSIX fcntl.h
的标准接口是open
。这是您应该从代码中调用的内容。领先的下划线是一个明确的提示,这是一个内部实现定义的东西。使用open
时,它应该是透明的。
对我而言,为什么在您的系统上完成此操作并不是很明显。利用这种宏重定向,例如可以基于编译时标志在不同的内部函数之间进行选择。因此,通常在#if
周围有一组#define
。对于文件功能,例如,在设置__USE_FILE_OFFSET64
时,这用于将默认版本重定向到64位版本。你必须这样做,因为你不能简单地改变现有功能的界面。
这样做的另一个原因可能是重定向功能,例如sprintf
更安全的版本,同样取决于编译器标志。或者让C代码实际调用与Fortran兼容的符号。
这也可能导致问题,例如尝试通过dlsym
执行功能时。