来自c标准库的函数的“隐含声明”? (头文件已包含在内)

时间:2016-04-18 14:09:38

标签: c compiler-warnings

函数gcvt包含在stdlib.h中。 当我尝试编译时:

    gcc -std=c99 problem.c 2.c -o problem

我得到了信息:

     warning: implicit declaration of function ‘gcvt’ [-Wimplicit-function-declaration]
 fstr = gcvt(datad,10,buff); 

无法正确执行。

但是我可以通过在功能测试之前在2.c中添加一行来解决这个问题:

   char *gcvt(double number, int ndigit, char *buf);

有谁知道为什么?

这是我的代码:

2.C

    #include "2.h"
    //char *gcvt(double number, int ndigit, char *buf);--must add this line
    void test() {

        double datad = 2.3;

        char buff[100];
        char *fstr; 
        fstr = gcvt(datad,10,buff); 


        printf("%s",fstr);
   }

2.H

    #ifndef XXX 
    #define XXX 
    #include<stdlib.h>
    #include<stdio.h>
    void test();
    #endif

problem.c

    #include "2.h"

    int main()
    {
        test();    
        return 0;
    }    

4 个答案:

答案 0 :(得分:4)

15年前,您要呼叫的功能已被标记为已废弃。阻止人们使用这些函数(没有实际破坏程序)的正常方法是将函数的实现保留在标准库中,但是从头文件中删除声明(或者至少使其难以启用)。

使用snprintf来完成同样的事情。

答案 1 :(得分:2)

gcc的手册页说:

  gcvt(): _SVID_SOURCE || _XOPEN_SOURCE >= 500

这意味着定义依赖于宏。

在之前添加任何#include指令:

#define _SVID_SOURCE

该手册页还建议您改为使用snprintf,因为gcvt已被弃用。

答案 2 :(得分:1)

在大多数系统上,-std=c99选项(实际上是gcc预定义的__STRICT_ANSI__宏)会导致系统标头遵循C标准,以了解它们可以在命名空间中公开的标识符。由于gcvt不是标准函数,因此无法公开。如果你想要它,你可能需要定义一个功能测试宏,如_XOPEN_SOURCE=600(问题6是单Unix规范的最后一个版本,以支持这个长期 - 过时的功能)包括任何标准标题之前;最简单的方法是在命令行上:

gcc -D_XOPEN_SOURCE=600 ...

但实际上你应该遵循其他答案的建议并使用snprintf,而不是这个长期过时的垃圾函数。

答案 3 :(得分:1)

gcvt()是否在标准库中是一个解释问题。它不属于C定义的标准库函数。它被记录为POSIX.1-2001中的遗留函数,但它已在POSIX.1-2008中完全删除,所以现在没有任何标准。< / p>

但实际上,它是 在Glibc中,而stdlib.h是其原型的正确标题,所以你可能会说它在标准库中那种感觉。就个人而言,我认为这是误导和/或误解。

查阅您并不完全熟悉的功能文档通常是个好主意。在这种情况下,您会在Glibc docs for this function中找到它具有功能测试宏要求:

  

因为glibc 2.12:

_SVID_SOURCE ||
    (_XOPEN_SOURCE >= 500 ||
        _XOPEN_SOURCE && _XOPEN_SOURCE_EXTENDED) &&
    !(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)

为了使原型可用,该预处理器条件必须在处理stdlib.h时评估为true。您可以通过确保符号_XOPEN_SOURCE定义为值500,并且_POSIX_C_SOURCE未定义或定义的值小于200112L来提供此功能。例如,将-D_XOPEN_SOURCE=500传递给gcc