隐式声明与GCC内建函数
来源:互联网 发布:2016中国网络视频报告 编辑:程序博客网 时间:2024/06/05 11:54
C语言隐式声明与GCC内建函数
- C语言隐式声明与GCC内建函数
- 什么是C语言的隐式声明
- GCC内建函数
- 隐式声明带来的灾难
什么是C语言的隐式声明
在C语言中,函数在调用前不一定非要声明。如果没有声明,那么编译器会自动按照一种隐式声明的规则,为调用函数的C代码产生汇编代码。下面是一个例子:
#include <stdio.h>int main() { double x = no_declare_func(); return 0;}
$ gcc -c implicitDeclare2.c $ gcc implicitDeclare2.o -o implicitDeclare2implicitDeclare2.o: In function `main':implicitDeclare2.c:(.text+0xe): undefined reference to `no_declare_func'collect2: error: ld returned 1 exit status
可以看到上面的代码没有定义no_declare_func,但是gcc在编译的时候并不会报错,因为C语言规定,对于没有声明的函数,自动使用隐式声明,也就变成如下代码(函数的隐式声明默认为int型):
#include <stdio.h>int no_declare_func();int main() { double x = no_declare_func(); return 0;}
在链接的时候会报错,因为链接过程中没有找到函数no_declare_func的定义。
目前C++是没有隐式声明这一说,遇到这种没有函数声明的情况,会直接报error。
GCC内建函数
内建函数(built-in),即一个系统或者工具提供的默认就能用的函数,我的理解是默认情况下,gcc在链接的时候如果没有找到定义,就会自动去链接库中对应名称的函数,gcc的内建函数大多是为了对代码进行优化。
gcc内建函数相关的选项如下:
-fbuiltin:
gcc编译默认选项,默认通过名字来识别内建函数-fno-builtin:
禁用GCC编译器内建函数。如果在gcc编译时用了-fno-builtin选项,则除非利用前缀__builtin_进行引用,否则不识别所有内建函数。例如,为了获得内建strcpy函数,应该调用__builtin_strcpy()而不是名为 strcpy() 的函数。-fno-builtin-xxx:
gcc编译时想特定的不使用某些函数的内建函数,例如,想使用除sqrt()之外的所有内建函数,则可以添加此选项-fno-builtin-sqrt
隐式声明带来的灾难
不要用隐式声明!!!不要用隐式声明!!!不要用隐式声明!!!
- 首先,隐式声明是默认int型,如果没有对应同名的内建函数,编译不报错,链接报错,这种情况上面已经介绍
- 有同名的内建函数,且类型相同,gcc编译链接没问题
- 有同名的内建函数,类型不同,链接报warning“隐式声明与内建函数不兼容”,但是以内建函数的函数原型为准。gcc编译器在编译时能够自动在常用库头文件(内建函数)中查找与隐式声明同名的函数,如果发现两者并不相同,则会按照内建函数的声明原型去生成调用代码。
case 2:
#include <stdio.h>int main(){ int x = abs(-1,2,3,4,5); printf("%d \n", x); return 0;}
其中,abs的隐式声明函数原型为:
int abs(int);
abs()内建函数原型为:
int abs(int);
gcc编译链接均没有报错,执行结果如下:
$ gcc -c implicitDeclare.c$ gcc implicitDeclare.o -o implicitDeclare$ ./implicitDeclare 1
可见,gcc的内建函数机制并不关心函数的参数,只是关心函数的返回值。虽然这个例子的运行结果都是正确的,但是这种正确是“碰巧”的,因为额外的函数参数并没有影响到结果。这种偶然正确是程序中要避免的。
case 3:
#include <stdio.h>int main(){ double x = sqrt(1); printf("%lf \n", x); return 0;}
其中,sqrt()的隐式声明函数原型为:
int sqrt(int);
sqrt()的内建函数原型为:
double sqrt(double);
编译报警告,链接按照内建函数原型链接:
$ gcc -c implicitDeclare.cimplicitDeclare.c: In function ‘main’:implicitDeclare.c:4:16: warning: incompatible implicit declaration of built-in function ‘sqrt’ [enabled by default] double x = sqrt(1); ^$ gcc implicitDeclare.o -o implicitDeclare
但是仍然可以执行,结果如下:
$ ./implicitDeclare 1.000000
- 隐式声明与GCC内建函数
- 隐式声明与内建函数不兼容
- 隐式声明与内建函数XXX不兼容
- 隐式声明与内建函数不兼容问题
- 隐式声明与内建函数不兼容问题
- 隐式声明与内建函数 xxx 不兼容
- 隐式声明与内建函数不兼容问题
- 隐式声明与内建函数 ‘memset’ 不兼容
- 解决隐式声明与内建函数不兼容问题
- 解决隐式声明与内建函数不兼容问题
- 隐式声明与内建函数malloc不兼容
- 警告:隐式声明与内建函数 ‘(函数名)’ 不兼容
- 解决linux下exit函数:隐式声明与内建函数‘exit’不兼容问题
- 警告: 隐式声明与内建函数‘strlen’不兼容 [默认启用] 警告: 隐式声明与内建函数‘maloc’不兼容 [默认启用]
- 警告:隐式声明与内建函数'exit'不兼容解决方案
- 编译的警告:隐式声明与内建函数 ‘malloc’ 不兼容
- 警告:隐式声明与内建函数‘malloc’不兼容
- 警告:隐式声明与内建函数 ‘malloc’ 不兼容
- .NET Core、Xamarin、.NET Standard和.NET Framework四者之间的区别
- 【Java基础】(01)类,继承,接口
- 欢迎使用CSDN-markdown编辑器
- JavaScript模板引擎Template.js使用详解
- android 屏幕分辨率
- 隐式声明与GCC内建函数
- bzoj2440 [中山市选2011]完全平方数(二分答案+莫比乌斯反演)
- 【强力推荐】资源下载的一个网站
- Redis介绍以及安装(Linux)以及遇到问题的解决办法
- 欢迎使用CSDN-markdown编辑器
- 工科英语积累本
- sqlite学习笔记(1)环境搭建
- iCarousel详解
- 侧边栏弹出导航插件