Why does gcc report “implicit declaration of funct

2020-07-07 04:53发布

问题:

I have the following C code:

#include <math.h>

int main(int argc, char ** argv)
{
    double mydouble = 100.0;
    double whatever = round(mydouble);

    return (int) whatever;
}

When I compile this, I get the warnings:

round_test.c: In function ‘main’:
round_test.c:6: warning: implicit declaration of function ‘round’
round_test.c:6: warning: incompatible implicit declaration of built-in function ‘round’

I'm rusty with C, but I thought that the #include brought a declaration for round() into scope. I've checked my ANSI standard (C99 is the only copy I have) which confirms that the round() function exists in the math.h header. What am I missing here?

Edit: The compiler is GCC 4.3.2 on Ubuntu (intrepid, IIRC). Running gcc -E gives:

$ gcc -E round_test.c | grep round
# 1 "round_test.c"
# 1 "round_test.c"
# 2 "round_test.c" 2
    double whatever = round(mydouble);

so the definition obviously isn't being found in the headers.

回答1:

I see you're using gcc.

By default, gcc uses a standard similar to C89. You may want to "force" it to use the C99 standard (the parts it complies with)

gcc -std=c99 -pedantic ...

Quote from GCC Manual

By default, GCC provides some extensions to the C language that on rare occasions conflict with the C standard. See Extensions to the C Language Family. Use of the -std options listed above will disable these extensions where they conflict with the C standard version selected. You may also select an extended version of the C language explicitly with -std=gnu89 (for C89 with GNU extensions) or -std=gnu99 (for C99 with GNU extensions). The default, if no C language dialect options are given, is -std=gnu89; this will change to -std=gnu99 in some future release when the C99 support is complete. Some features that are part of the C99 standard are accepted as extensions in C89 mode.



回答2:

Something must be wrong with your gcc installation, system headers, or compilation options.

Try compiling with -E. That will show you what the preprocessor output -- including which headers are being included and what's in them. On my Ubuntu Linux system it's about 1000 lines of output, including this:

extern double round (double __x) __attribute__ ((__nothrow__)) __attribute__ ((__const__));


回答3:

You need to tell gcc that you want C99, and that you want to link in libm:

gcc -std=c99 -lm round_test.c


回答4:

The code you type compiles cleanly on MacOS X 10.5.8 with GCC 4.0.1. If prodded with options '-Wall -Wextra', it complains about unused parameters argc and argv - not material.

Have you looked in <math.h> on your machine?

Have you tried with options such as '-stc=c99'?



回答5:

C99 was the answer, but the full story is a little more complicated. The reason I'd been playing with this at all was that I was trying to compile a library written for Windows, which had its own "optimised" definition of round(). I got a linker error telling me that the definition conflicted with the built-in, so I removed the definition (and declaration). Once I'd done that I started to get the "implicit declaration error".

It seems that the default compile mode (without the -std=c99 flag) is neither conforming C89 nor C99: if it were conforming C89, you should be able to provide a custom definition of round() without conflicting, and if it were conforming C99 the declaration should be in math.h.



回答6:

you need to link with the math library. So when you compile, be sure to add the -lm flag.