编程范式 ,11/11/18

1 GCC编译过程中的一些有意思的问题与过程
以下代码:

#include <stdlib.h>
#include <stdio.h>
#assert <assert.h>
int main ( int argc, char * argv)
{
	void * memory = malloc(400);
	assert (memory  != NULL);
	printf(" Yay!\b");
	free(memory);
	return 0;
}

如果注释掉#include <stdio.h>,printf 缺少声明,但是GCC一般不会报错程序还是能够link完成:
GCC会推测调用的函数的原型,在标准库中找到相应的原型;
注释掉#include <stdlib.h>,失去malloc 和 free 函数的原型,但是仍然能够通过最终链接;
注释掉#assert <assert.h>,编译时会生成的.o文件中会生成call assert()的汇编指令,导致最后链接失败(没有assert函数的实现定义)
注意:函数的原型能够在编译时在活动的栈记录中开辟出地址用于存储出函数形参的参数存储空间;
2 当函数调用参数多于原型的形参个数的情况:

int main ()
{
	int num = 65;
	int length = strlen( (char*)&num, num);
	printf( "length = %d\n",length);
    return 0;
}
(大端系统)程序最终会输出 0
编译时strlen函数()会开辟SP =SP-8的内存空间当函数原型参数的,而链接时根据标准库实际代码汇编结果,只会调用一个参数,得到相应的地址。会忽略参数个数的错误。(编译是编译,链接是链接)


3 参数写少了

int memcmp( void* v1); //原型搞错了、
{
int n = 17;
int m = memcmp(&n);
}
编译时函数只给了一个参数内存空间,链接时会按照库函数中的原型,将nm变量预先开辟的内存空间,作为函数参数进行运算;

4 debug 错误
seg fault : 尝试对空指针进行解引用
bus fualt:内存地址赋值错误(非法)(有点复杂)
5 数组越界问题
int main()
{
int i ;
int array[4];
for (i = 0; i<=4; i++{
array[i] = 0;}
return 0;
}
程序会死循环:array[4] =0 , 会导致栈区顶端 i =0;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值