This question was migrated from Unix & Linux Stack Exchange because it can be answered on Stack Overflow. Migrated9个月前。Learn more
背景
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

其中一个使用GNUcrypt.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声明,这让人更加困惑。

最佳答案

这是两个声明,而不是两个定义。头文件的内容对包含函数的定义没有影响:这由链接器决定。Unix C标准库中的crypt函数只有一个定义,它是cryptlibcrypt.a中的符号指向的任何内容(取决于您是静态链接还是动态链接)。
由于这两个声明是兼容的,所以程序通过哪个头并不重要。如果两个声明都被处理了,也没关系:一个程序可以包含任意数量的函数声明,只要它们是兼容的。如果两个函数声明具有相同的返回类型、相同数量的参数以及每个参数的相同类型,则不必详细说明(请参阅C语言规范)。声明中给出的参数名称不重要。

关于compilation - unistd.h和crypt.h中的crypt有什么区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54475384/

10-11 20:55