1. 类型长度问题
长度(单位bit)
| C TYPE | 32位 | 64位 |
|---|---|---|
| char | 8 | 8 |
| short | 16 | 16 |
| int | 32 | 32 |
| long | 32 | 64 |
| long long | 64 | 64 |
| float | 32 | 32 |
| double | 64 | 64 |
| 指针 (*) | 32 | 64 |
主要的不同点在于 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 * | 32 | 64 |
| int | 32 | 32 |
在32位平台,char *hello() 返回一个32位地址,隐式声明为 int hello() ,返回值不变。
在64位平台,char *hello() 返回一个64位地址,隐式声明为 int hello() ,返回值被强制转换为32位。
因此返回指针类型的隐式声明函数在32位平台仍然可以正常调用,但在64位平台会出现异常。
建议
编译代码的时候加上 -Wall -Werror 这两个参数,
-Wall: 打开所有警告信息
-Werror: 将所有警告信息当作错误
本文探讨了从32位到64位编译过程中类型长度的变化及函数未声明所带来的问题,强调了开启-Wall和-Werror的重要性。
4376

被折叠的 条评论
为什么被折叠?



