incompatible implicit declaration of built-in function ‘xyz’

使用了malloc、exit、strlen却没有 #include ,有warning出现
warning: incompatible implicit declaration of built-in:     function ‘strlen'


来说说这个 warning,首先你必须知道:



        C90 标准允许使用一个函数时,不需要提供原型宣告,因为编译器会
        假定该函数的返回型态是 int。至于堆叠平衡的需求,因为这一类函数
        的堆叠是由 caller 负责清理,所以没有原型宣告,还是能正确维持平衡。


        C99 不允许上述行为,C++ 也是。


        gcc 比 VC 在这方面还要鸡婆,它的编译器会事先储存 C 标准函数的
        原型宣告资讯,而且预设就会使用这部份资讯,除非你在编译时,使用
        这个参数:
                  -fno-builtin


举例来说,当有以下程式码时:


        #include
        #include


        int main() {
          printf("%f\n", sqrt(16.0));


          return 0;
        }


gcc 使用 C90 标准编译: gcc -std=c90 ss.c
会出现警告讯息:
                warning: incompatible implicit declaration of built-in
                function 'sqrt' [enabled by default]


                printf("%f\n", sqrt(16.0));
                               ^


意思是,在隐式宣告下,其原型资讯为 int sqrt(double);
但是这个内建函数的原型,已查出是 double sqrt (double x);
因此两者不相容 (incompatible),而 gcc 将会主动使用内建的原型宣告。
主要是警告 VC 使用者,这里不会跟 VC 一样,当成 int sqrt(double) 来用。


※ 上面的程式执行结果是:4.000000


如果改成这样编译:gcc -std=c90 -fno-builtin ss.c
则不会有警告讯息,而且程式执行结果会跟 VC 编译出来的一样,都是 0.000000。
原因并不难理解,因为 sqrt 函数把返回值放在专门存放 double 的地方,可是
编译器以为他的返回值是 int,所以跑去另一个地点取值,最后取到错误的资讯。



附带一提,如果是 C++ 编译器,会直接编译错误,如果是 C99 编译的话:


        gcc -std=c99 -fno-builtin ss.c
        ss.c: In function 'main':
        ss.c:5:3: warning: implicit declaration of function 'sqrt'
        [-Wimplicit-function-declaration]
           printf("%f\n", sqrt(16.0));
           ^


这个错误讯息,是由于 C99 标准不想像 C90 这样,隐含的把函数返回值当成 int,

但是又不想害以前的 C90 使用者编译失败,所以只提出警告。


https://www.ptt.cc/bbs/C_and_CPP/M.1416824909.A.E7F.html

https://stackoverflow.com/questions/977233/warning-incompatible-implicit-declaration-of-built-in-function-xyz

https://stackoverflow.com/questions/11380744/i-used-pow-function-in-my-c-program-but-did-not-link-to-lm-it-still-worked-w

你可能感兴趣的:(gcc)