背景
crypt
有两个定义,from the docs,
其中一个使用
unistd.h
#define _XOPEN_SOURCE /* See feature_test_macros(7) */ #include <unistd.h>
这定义为
#ifdef __USE_MISC extern char *crypt (const char *__key, const char *__salt) __THROW __nonnull ((1, 2)); #endif
其中一个使用 GNU
crypt.h
#define _GNU_SOURCE /* See feature_test_macros(7) */ #include <crypt.h>
这定义为
extern char *crypt (const char *__phrase, const char *__salt) __THROW __nonnull ((1, 2));
问题
当我用第一个例子中的定义编译时(unistd.h
)
#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>
int main()
{
printf("%s", crypt("foobar", "sa"));
}
我遇到了错误
In function ‘main’:
warning: implicit declaration of function ‘crypt’; did you mean ‘chroot’? [-Wimplicit-function-declaration]
printf("%s", crypt("foobar", "sa"));
^~~~~
chroot
warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
printf("%s", crypt("foobar", "sa"));
~^ ~~~~~~~~~~~~~~~~~~~~~
%d
出于绝望,我尝试添加这个。
#define _XOPEN_VERSION 700
#define _POSIX_VERSION 200809L
#define __USE_MISC 1
在 Ubuntu Trusty 14.04 上,我相信使用 unistd.h
声明可以正常工作,这会让人更加困惑。
最佳答案
这是两个声明,而不是两个定义。头文件的内容对包含哪个函数定义没有影响:这由链接器决定。 crypt
函数在 Unix C 标准库中只有一个定义,它是 libcrypt.a
中 crypt
指向的任何符号或 libcrypt.so
(取决于您是静态链接还是动态链接)。
由于这两个声明是兼容的,所以程序通过哪个 header 并不重要。如果两个声明都被处理也很好:一个程序可以包含任意数量的函数声明,只要它们是兼容的。无需深入了解具体细节(请参阅 C 语言规范),如果两个函数声明具有相同的返回类型、相同数量的参数以及每个参数的相同类型,则它们是兼容的。声明中给出的参数名称并不重要。
关于compilation - unistd.h 和 crypt.h 中的 crypt 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54475384/