compilation - unistd.h 和 crypt.h 中的 crypt 有什么区别?

标签 compilation c posix crypt

背景

crypt 有两个定义,from the docs,

  1. 其中一个使用 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
    
  2. 其中一个使用 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.acrypt 指向的任何符号或 libcrypt.so(取决于您是静态链接还是动态链接)。

由于这两个声明是兼容的,所以程序通过哪个 header 并不重要。如果两个声明都被处理也很好:一个程序可以包含任意数量的函数声明,只要它们是兼容的。无需深入了解具体细节(请参阅 C 语言规范),如果两个函数声明具有相同的返回类型、相同数量的参数以及每个参数的相同类型,则它们是兼容的。声明中给出的参数名称并不重要。

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

相关文章:

javascript - HTML,编译还是不编译...外部?

c - 列表,C中指针和语义的命名别名

linux - 程序如何获取 sigwaitinfo() 返回的 siginfo_t 结构中的消息队列描述符

c - glibc - 获取具有包含指定地址的符号的共享库句柄

c - 如果已经达到空终止符, write() 会写什么?

pthreads - pthread_create 和 EAGAIN

Linux : How can i find compilation flag of library provided by Opensuse i. e libOSmesa.so?

javascript - 组件和 cms 驱动应用程序的 AngularJS 最佳实践

compilation - 如何在一个不在 RoR 上运行的小项目中将我的 HAML 文件自动编译为 HTML 文件?

c - 如何将二进制数组放入二进制文件