Linux平台开发 64位与32位问题

本文探讨了从32位到64位编译过程中类型长度的变化及函数未声明所带来的问题,强调了开启-Wall和-Werror的重要性。

1. 类型长度问题

长度(单位bit)

C TYPE32位64位
char88
short1616
int3232
long3264
long long6464
float3232
double6464
指针 (*)3264

主要的不同点在于 long指针,这两种类型都由 32bit 变为 64bit

同样需要注意的有:

  • time_t 时间类型,因为其在Linux平台中的定义为 typedef long time_t;
  • 结构体包含 long 或者指针成员的,其结构体大小也会有变化。

2. 函数未声明问题

在C语言中,函数在调用之前可能没有声明。
如果没有声明,那么编译器会自动按照一种隐式声明的规则。

下面是一个例子:

#include <stdio.h>

int main(int argc, char** argv)
{
  char *p;
  p = hello();
  printf("%s\n", p);
  return 0;
}

编译上述代码(编译但不链接 gcc -Wall -c xx.c),会有以下警告信息但不会报错:

warning: implicit declaration of function ‘hello’
warning: assignment makes pointer from interger without a cast

先看第一句警告 warning: implicit declaration of function ‘hello’
该警告信息产生的原因是 hello() 函数被使用前没有声明,因此编译器会输出这个警告信息。

出现这种情况后,编译器会自动使用隐式声明,相当于以下代码

#include <stdio.h>

int hello();
int main(int argc, char** argv)
{
  char *p;
  p = hello();
  printf("%s\n", p);
  return 0;
}

这个时候就可以解释第二个警告信息
warning: assignment makes pointer from interger without a cast
hello() 函数按照隐式声明,返回类型 int 给字符指针 p,因此出现警告信息。

函数未声明导致的问题

当隐式声明函数名称恰好在链接库中存在,编译可以通过,
但是隐式声明的函数实际返回并非都是int类,就会带来隐患。

char *hello()int hello() 为例,

返回值长度32位64位
char *3264
int3232

在32位平台,char *hello() 返回一个32位地址,隐式声明为 int hello() ,返回值不变。
在64位平台,char *hello() 返回一个64位地址,隐式声明为 int hello() ,返回值被强制转换为32位。
因此返回指针类型的隐式声明函数在32位平台仍然可以正常调用,但在64位平台会出现异常。

建议

编译代码的时候加上 -Wall -Werror 这两个参数,

-Wall: 打开所有警告信息
-Werror: 将所有警告信息当作错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值