programforjoy
programforjoy

Reputation: 499

"Implict declaration" of a function from c standard library? (the header file has already been included)

the function gcvt is included in stdlib.h. When I try to compile this:

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

I got the imformation:

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

And It can't be executed correctly.

But I can fix this by adding one line in 2.c before function test:

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

Does anyone know why ?

Here is my code:

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;
    }    

Upvotes: 1

Views: 3755

Answers (4)

John Bollinger
John Bollinger

Reputation: 181149

Whether gcvt() is in the standard library is a matter of interpretation. It is not among the standard library functions defined by C. It was documented as a legacy function in POSIX.1-2001, but it has been altogether removed in POSIX.1-2008, so these days there is nothing standard about it.

As a practical matter, however, it is in Glibc, and stdlib.h is the correct header for its prototype, so you might say it's in the standard library in that sense. Personally, I consider that misleading and / or misunderstood.

It is generally a good idea to consult the documentation of functions that you are not completely familiar with. In this case, you will find in the Glibc docs for this function that it has a feature-test macro requirement:

Since glibc 2.12:

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

In order for the prototype to be available, that preprocessor conditional must evaluate to true while stdlib.h is being processed. You might provide for that by ensuring that the symbol _XOPEN_SOURCE is defined with value 500, and that _POSIX_C_SOURCE is either undefined, or defined with a value less than 200112L. For example, pass -D_XOPEN_SOURCE=500 to gcc.

Upvotes: 1

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215457

On most systems, the -std=c99 option (actually the __STRICT_ANSI__ macro that gcc predefines as a result) causes the system headers to adhere to the C standard for what identifiers they can expose in the namespace. Since gcvt is not a standard function, it cannot be exposed. If you want to request it, you'll probably need to define a Feature Test Macro like _XOPEN_SOURCE=600 (Issue 6 was the last version of the Single Unix Specification to support this long-obsolete function) before including any of the standard headers; the easiest way to do this is on the command line:

gcc -D_XOPEN_SOURCE=600 ...

But really you should follow the advice of the other answers and use snprintf, not this long-obsolete junk function.

Upvotes: 1

Klas Lindb&#228;ck
Klas Lindb&#228;ck

Reputation: 33273

The man page for gcc says:

  gcvt(): _SVID_SOURCE || _XOPEN_SOURCE >= 500

This means that the definition is dependent on a macro.

Add this before any #include directives:

#define _SVID_SOURCE

The man page also recommends that you use snprintf instead, because gcvtis deprecated.

Upvotes: 2

Art
Art

Reputation: 20402

The function you want to call has been marked as obsolete 15 years ago. The normal way to discourage people from using those functions (without actually breaking programs) is to have the implementation of the function left in the standard library, but remove the declaration from header files (or at least make it hard to enable).

Use snprintf instead to accomplish the same thing.

Upvotes: 4

Related Questions