[英]What is the difference between crypt in unistd.h and crypt.h?
crypt
has two definitions, from the docs, crypt
有两个定义, 来自docs,
One of them uses unistd.h
其中一个使用unistd.h
#define _XOPEN_SOURCE /* See feature_test_macros(7) */ #include <unistd.h>
This is defined as 这被定义为
#ifdef __USE_MISC extern char *crypt (const char *__key, const char *__salt) __THROW __nonnull ((1, 2)); #endif
One of them uses GNU crypt.h
其中一个使用GNU crypt.h
#define _GNU_SOURCE /* See feature_test_macros(7) */ #include <crypt.h>
This is defined as 这被定义为
extern char *crypt (const char *__phrase, const char *__salt) __THROW __nonnull ((1, 2));
When I compile with the definition in the first example ( unistd.h
) 当我用第一个例子中的定义编译时( unistd.h
)
#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>
int main()
{
printf("%s", crypt("foobar", "sa"));
}
I'm getting the error 我收到了错误
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
Out of desperation, I've tried adding this. 出于绝望,我尝试添加这个。
#define _XOPEN_VERSION 700
#define _POSIX_VERSION 200809L
#define __USE_MISC 1
On Ubuntu Trusty 14.04 I believe this works fine use the unistd.h
declaration, which makes all the more confusing. 在Ubuntu Trusty 14.04上,我相信这可以很好地使用unistd.h
声明,这使得更加混乱。
These are two declarations , not two definitions . 这是两个声明 ,而不是两个定义 。 The content of the header file has no impact on which definition of a function is included: this is determined by the linker. 头文件的内容对包含函数定义没有影响:这由链接器决定。 There is only one definition of the crypt
function in the Unix C standard library, it's whatever the symbol crypt
points to in libcrypt.a
or libcrypt.so
(depending on whether you link statically or dynamically). 在Unix C标准库中只有一个crypt
函数的定义,它是libcrypt.a
或libcrypt.so
符号crypt
指向的内容(取决于您是静态链接还是动态链接)。
Since the two declarations are compatible, it doesn't matter which header a program gets its through. 由于这两个声明是兼容的,因此程序通过哪个标头并不重要。 It's also fine if both declarations are processed: a program can contain any number of declarations for a function as long as they're compatible. 如果两个声明都被处理,那也没关系:一个程序可以包含任意数量的函数声明,只要它们兼容即可。 Without going into the exact details (refer to the C language specification), two function declarations are compatible if they have the same return type, the same number of arguments and the same type for each argument. 在没有详细说明(参考C语言规范)的情况下,如果两个函数声明具有相同的返回类型,相同数量的参数以及每个参数的相同类型,则它们是兼容的。 The name of the argument given in a declaration is not significant. 声明中给出的参数名称并不重要。
You should ignore unistd.h
. 你应该忽略unistd.h
。 That declaration is there for POSIX compatibility but GLIB has removed the definition for crypt
when they migrated to libxcrypt
to develop those features in isolation of glibc. 该声明适用于POSIX兼容性,但GLIB在迁移到libxcrypt
时删除了crypt
的定义,以便在libxcrypt
使用glibc的情况下开发这些功能。 This means you can still get ABI-compatibility but must link in the crypt
. 这意味着您仍然可以获得ABI兼容性,但必须链接到crypt
。 You can read more about that here 你可以在这里阅读更多相关信息
Availability in glibc glibc中的可用性
The
crypt ()
,encrypt ()
, andsetkey ()
functions are part of the POSIX.1-2008 XSI Options Group for Encryption and are optional.crypt ()
,encrypt ()
和setkey ()
函数是POSIX.1-2008 XSI加密组选项组的一部分,是可选的。 If the interfaces are not available then the symbolic constant_XOPEN_CRYPT
is either not defined or defined to -1, and can be checked at runtime withsysconf ()
. 如果接口不可用,则符号常量_XOPEN_CRYPT
未定义或定义为-1,并且可以在运行时使用sysconf ()
进行检查。This may be the case if the downstream distribution has switched from glibc crypt to
libxcrypt
. 如果下游分发已从glibc crypt切换到libxcrypt
则可能是这种情况。 When recompiling applications in such distributions the user must detect if_XOPEN_CRPYT
is not available and include crypt.h for the function prototypes; 在这种发行版中重新编译应用程序时,用户必须检测_XOPEN_CRPYT
是否不可用,并为函数原型包含crypt.h; otherwiselibxcrypt
is a ABI compatible drop-in replacement. 否则libxcrypt
是ABI兼容的直接替代品。
As for why even if you link the definition isn't pulled down with 至于为什么即使你链接定义也没有被拉下来
#define _XOPEN_VERSION 700
#define _POSIX_VERSION 200809L
#define __USE_MISC 1
#define _XOPEN_SOURCE
Well there are a few things that happening there 那里发生了一些事情
unistd.h
is __USE_MISC
. unistd.h
唯一重要的标题是__USE_MISC
。 unistd.h
includes features.h
which undef
s the __USE_
macros to start with a "clean slate" unistd.h
包括features.h
其undef
S中__USE_
宏开始一个“清白” __USE_MISC
is to have defined _GNU_SOURCE
. 定义__USE_MISC
的唯一方法是定义_GNU_SOURCE
。 If you want to pull in the declaration of crypt.h
from unistd.h
you must define _GNU_SOURCE
! 如果你想从unistd.h
中crypt.h
的声明,你必须定义_GNU_SOURCE
! Those two examples cited from man page of crypt.h
do the same thing and whether you include unistd.h
or crypt.h
you MUST also define _GNU_SOURCE
in contemporary versions of glibc. 从crypt.h
man页面引用的这两个例子做同样的事情,无论你是否包含unistd.h
或crypt.h
你还必须在当前版本的glibc中定义_GNU_SOURCE
。
So you can either do, 所以你可以这样做,
#define _GNU_SOURCE
#include <unistd.h>
Or, 要么,
#define _GNU_SOURCE
#include <crypt.h>
But because you must link against crypt
( -lcrypt
) I would suggest using the declaration in crypt.h
for sanity. 但是因为你必须链接crypt
( -lcrypt
),我建议使用crypt.h
的声明来保持理智。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.