Compilation unistd.h中的crypt与crypt.h有什么区别? 背景
Compilation unistd.h中的crypt与crypt.h有什么区别? 背景,compilation,c,posix,crypt,Compilation,C,Posix,Crypt,crypt有两种定义 其中一个使用unistd.h #define _XOPEN_SOURCE /* See feature_test_macros(7) */ #include <unistd.h> #define _XOPEN_SOURCE #include <unistd.h>
crypt
有两种定义
unistd.h
#define _XOPEN_SOURCE /* See feature_test_macros(7) */
#include <unistd.h>
#define _XOPEN_SOURCE
#include <unistd.h>
#include <stdio.h>
int main()
{
printf("%s", crypt("foobar", "sa"));
}
crypt.h
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <crypt.h>
unistd.h
)
出于绝望,我尝试添加这个
#define _XOPEN_VERSION 700
#define _POSIX_VERSION 200809L
#define __USE_MISC 1
在UbuntuTrusty 14.04上,我相信使用unistd.h
声明可以很好地实现这一点,这让人更加困惑。这是两个声明,而不是两个定义。头文件的内容对包含函数的定义没有影响:这由链接器决定。Unix C标准库中的crypt
函数只有一个定义,它是libcrypt.a
或libcrypt.so
中的crypt
符号指向的任何对象(取决于静态链接还是动态链接)
由于这两个声明是兼容的,所以程序通过哪个头并不重要。如果两个声明都被处理也没关系:一个程序可以包含任意数量的函数声明,只要它们是兼容的。如果两个函数声明具有相同的返回类型、相同数量的参数和每个参数的相同类型,则它们是兼容的,而不必详细说明(请参阅C语言规范)。声明中给出的参数名称不重要。您应该忽略
unistd.h
。该声明是为了POSIX兼容性,但GLIB在迁移到libxcrypt
以独立于glibc开发这些功能时删除了crypt
的定义。这意味着您仍然可以获得ABI兼容性,但必须链接到crypt
。你可以阅读更多关于这方面的内容
glibc中的可用性
crypt()
、encrypt()
和setkey()
函数是用于加密的POSIX.1-2008 XSI选项组的一部分,是可选的。如果接口不可用,则符号常量\u XOPEN\u CRYPT
未定义或定义为-1,可以在运行时使用sysconf()
进行检查
如果下游发行版已从glibc crypt切换到libxcrypt
,则可能出现这种情况。在此类发行版中重新编译应用程序时
用户必须检测\u XOPEN\u CRPYT
是否不可用,并将crypt.h包含在函数原型中;否则,libxcrypt
是与ABI兼容的插入式替代品
至于为什么即使你将定义与
#define _XOPEN_VERSION 700
#define _POSIX_VERSION 200809L
#define __USE_MISC 1
#define _XOPEN_SOURCE
这里发生了一些事情
unistd.h
中唯一重要的标题是\uuuuu USE\umisc
unistd.h
包括功能.h
其中\u USE\u MISC
的唯一方法是定义\u GNU\u SOURCE
unistd.h
中提取crypt.h
的声明,必须定义\u GNU\u SOURCE
引用的这两个示例做了相同的事情,无论您包括unistd.h
还是crypt.h
,您都必须在当代版本的glibc中定义\u GNU\u SOURCE
所以你可以
#define _GNU_SOURCE
#include <unistd.h>
定义GNU源
#包括
或者
定义GNU源
#包括
但是,因为您必须链接到
crypt
(-lcrypt
),我建议您使用crypt.h
中的声明来保持理智。这是一个关于C的问题,而不是关于Linux的使用或管理。这是我的想法,但我知道其中一些内容是在内部定义的,并且会产生一些深刻的巫毒(至少使用c99.h magic)。如果它们是相同的定义,为什么crypt
函数没有在内部定义。它是在库中定义的,而不是编译器本身可以为其生成代码的那些函数中的任何一个。深层巫毒是用于声明的条件包含,而不是定义。声明此函数的两个标头h不同的预处理器保护。要从unistd.h
获取声明,需要定义哪些预处理器符号是您的另一个问题。
#define _XOPEN_VERSION 700
#define _POSIX_VERSION 200809L
#define __USE_MISC 1
#define _XOPEN_VERSION 700
#define _POSIX_VERSION 200809L
#define __USE_MISC 1
#define _XOPEN_SOURCE
#define _GNU_SOURCE
#include <unistd.h>
#define _GNU_SOURCE
#include <crypt.h>