我们在编写C/C++程序时,32位程序和64位程序的代码有何区别?如何编写既可以编译成32位程序又可以编译成64位程序的代码?

代码上的区别

实际上,对于32位程序和64位程序来说,代码上的区别不大,严格来说,甚至是一样的,它的主要区别在于一些基本数据类型占用的字节长度不一样(注:这里仅针对类Unix平台

类型 32位占用字节 64位占用字节
long 4 8
unsigned long 4 8
指针 4 8

当然这里的long包括一些用它定义的类型,如time_t,它的长度也是有区别的,关于time_t,还有一个有意思的问题《什么是2038问题》。

除此之外,其默认对齐字节数,也不一样,32位程序为4字节,64位程序默认为8字节。关于字节对齐,可参考《理一理字节对齐的那些事》。

可执行文件上的区别

来看个小例子吧,看看他们有何区别。

//来源:公众号编程珠玑
//作者:守望先生
test.c
#include<stdio.h>
struct Test
{int a;long b;
};
int main(void)
{printf("sizeof(long) = %zu\n",sizeof(long)); //long类型占用字节数printf("sizeof(unsigned long) = %zu\n",sizeof(unsigned long));//unsigned long类型占用字节数struct Test test = {1,2};printf("sizeof(struct Test) = %zu\n",sizeof(test));//用于测试对齐字节数printf("sizeof(pointer) = %zu\n",sizeof(&test)); //指针占用字节数return 0;
}

如果你的系统是64位,默认编译为64位程序,而如果需要编译为32位程序,则需要带上-m32参数,如果你的系统是32位的,那么是不能直接运行64位程序的,但是如果是64位的,是可以运行32位程序的。(实际上你在下载软件的时候需要选择位数的时候,就需要注意了,如果你的系统32位的, 但是你下载了一个64位的程序包,自然是不可用的,但是反过来却可以。)

编译为32位程序运行:

$ gcc -o  test32 test.c -m32
$ ./test32
sizeof(long) = 4
sizeof(unsigned long) = 4
sizeof(struct Test) = 8
sizeof(pointer) = 4

编译位64位程序运行:

$ gcc -o test64 test.c
$ ./test64
sizeof(long) = 8
sizeof(unsigned long) = 8
sizeof(struct Test) = 16
sizeof(pointer) = 8

通过运行结果,我们也可以看出前面提到的差别。

那么可执行文件本身有什么差别呢?

$ readelf -h test32
ELF Header:Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 Class:                             ELF32Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              EXEC (Executable file)Machine:                           Intel 80386(...)

可以看到Class属性标识为ELF32。

而对于64位:

readelf -h test64
ELF Header:Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class:                             ELF64Data:                              2's complement, little endianVersion:                           1 (current)OS/ABI:                            UNIX - System VABI Version:                       0Type:                              EXEC (Executable file)Machine:                           Advanced Micro Devices X86-64

它的属性为ELF64。实际上我们可以通过readelf发现很多信息。
例如你在进行交叉编译后出现链接错误或者最后的执行程序在目标机器无法运行,则可以查看Machine部分,看看程序是否能在你想要的平台运行。

例如64位程序中的Machine中显示的是Advanced Micro Devices X86-64,至少说明它在arm平台是没法正常运行的。

elf文件中的一些相关信息已经在《一个elf文件包含了多少信息?》中介绍了,有兴趣的可以移步前往阅读。

一个程序最大能申请多少内存空间?

还记得这道面试题吗?如果你只是回答Linux理论最大不超过3G,windows不超过G,那肯定是不完整的,这里必须要区分32位程序和64位程序。

这一点在《解引用NULL为什么会挂死?》中已经有所提及。32位决定了其虚拟地址空间的最大值为2^32,即4G,除去操作系统占用的1G左右,剩下3G左右,当然了这里面3G包含了所有代码,数据等,总结就是,最终能使用的不超过3G。不到3G的地址空间。(注这里并不表示它只能访问计算机4G的内存,而是表示最大寻址范围为4G)。那么64位的虚拟地址空间扩展到了17179869184G,所以,看出差别了吗?

通过上面简单的分析可以发现,64位程序理论能使用的内存是惊人的,而32位程序却非常有限,除此之外,还有一个在《什么是2038问题》》中提到的问题,就是2038年后,32位程序将很难正常使用时间相关的处理。

当然了,64位系统通常能够支持更高精度的浮点运算。

同时支持32位和64位代码编写原则

基于前面提到的原因,很多传统系统都开始着手移植到64位系统上,而如果原先代码就非常规范的话,移植工作还算比较轻松,链接64位库,编译成64位程序即可,但是如果没有遵循以下原则,那么工作量就比较大了:

  • 依赖long类型和指针类型占用空间大小以及其表示范围

当然,对于这个原则,其表现可能非常多。

long和int混用

例如:

void test(long len)
{int localLen = len;xxxx;
}

这里很明显可能会发现截断。最常见的就是:

int len = sizeof(xxx);

当然,这里大多数情况下也不会有太大问题,直到其长度大于int表示范围。

慎用掩码定义

我们可能经常需要定义一些掩码:

long mask = OxFFFFFFFFL;

在 32 位系统上,这会将所有位都置位(每位全为 1),但是在 64 位系统上,只有低 32 位被置位了。结果是这个值是 0x00000000FFFFFFFF。
如果希望所有位置1,那么可以:

long mask = -1'\;

打印指针

32下,这样的没问题的:

int a = 10;
int *p = &a;
printf("%x",p);

但是64位下,打印不完全。自然要使用:

printf("%p",p);

传送结构体数据

在32位和64位系统中,其默认对齐字节数是不一样的。

strcut test
{int a;long b;
}

如果对方是64位,发送过来上述结构体数据,而你的是32位程序,可想而知,结果并不会如你所愿。前面占用空间16字节,而后者占用空间8字节。

显示定义long

如果你的数据类型是long,那么可以使用L显示说明:

long i = 1 << a;

上面的写法建议换成:

long i  = 1L << a;

避免数据被截断。

总结

关于这样的点还有很多,这里不一一介绍。本文简单介绍了32位程序和64位程序的区别,以及移植过程中需要注意的原则。实际上编写同时能够运行在32位和64位系统上的整体原则基本如下:

  • 不要试图假定数据类型的占用空间

  • 显示区别使用int和long

而前面提到的一些问题,其实通过一些代码检查工具就很容易发现了,不放过小的警告,基本能解决大部分问题。

关注公众号【编程珠玑】,获取更多Linux/C/C++/数据结构与算法/计算机基础/工具等原创技术文章。后台免费获取经典电子书和视频资源

32位程序和64位程序这些区别你知道吗?相关推荐

  1. [思考]-32位的应用程序和64位的应用程序有什么区别

    文章目录 1.32位的应用程序和64位的应用程序有什么区别 2.在aarch64的linux os中,是否同时支持运行32位app和64位app ★★★ 链接 : 个人博客导读首页-点击此处 ★★★ ...

  2. 使用.netFx4.0提供的方法解决32位程序访问64位系统的64位注册表

    原文:使用.netFx4.0提供的方法解决32位程序访问64位系统的64位注册表 我们知道目标平台是32位的程序运行在64位的系统上,去访问部分注册表的时候系统自动重定向到win32node节点对应的 ...

  3. linux32位运行64位程序,32位windows下可以运行的程序在64位linux下报错

    已结贴√ 问题点数:20 回复次数:3 32位windows下可以运行的程序在64位linux下报错 filt.c在32位windows code:blocks 10.05下运行无任何异样. 传到64 ...

  4. 32位dll转64位工具_如何在64位系统中运行32位或16位程序

    由于CPU和系统架构的更新,现行主流的Windows系统已经是64位.然而许多人还恋恋不舍的一些老游戏或老程序已经没有了更新.在64位的系统上运行这些程序,往往会出现运行故障.如何才能解决这个烦心事? ...

  5. 32位程序和64位程序

    我们有时候会遇到这样一种情况:我们在32位操作系统上下载了64位版本的程序,却发现无法安装,大家可能会很困惑. 下面就来简单解释一下32位程序与64位程序的具体区别. 我们首先要弄明白的: 1.这里所 ...

  6. 32位程序在64位系统上运行

    32位程序在64位系统上运行 32位系统下的MFC文件,怎么在64位的系统上面运行? 先将32位的应用程序转换为64位的应用程序. 从32位应用程序到64位应用程序 编译:starlight 这篇文章 ...

  7. c语言的程序是32位还是64位,在C语言中,对于32位计算机和64位计算机,long的大小是多少?...

    本问题已经有最佳答案,请猛点这里访问. 对于32位平台,C中的long的大小为4字节,而对于64位平台,为8字节是否正确? 通常,但不一定. 如果要使用固定大小的类型,请使用int32_t或int64 ...

  8. 32位应用程序操作64位Windows注册表的方法

    64位的Windows操作系统中能够运行32位的应用程序,主要是由于Windows中提供了WOW64子系统. 1.WOW64子系统 WOW64 (Windows-on-Windows 64-bit)是 ...

  9. 32位程序注入64位DLL到64位进程

    向其他进程注入DLL通常的做法是通过调用CreateRemoteThread这个API在目标进程内创建一个远程线程,用这个线程来调用LoadLibraryA或LoadLibraryW(下文统称Load ...

最新文章

  1. git 创建分支,更改并提交
  2. linux python3安装包_Linux下安装python3及相关包
  3. 「AI初识境」近20年深度学习在图像领域的重要进展节点
  4. 数据库事务的隔离级别 (转)
  5. 增强QQ空间的统计功能
  6. 模拟器不全屏_刺激战场:腾讯模拟器怎么设置才不卡
  7. html固定dl高度_HTML入门笔记1
  8. java学习(43):值参数传递
  9. uc浏览器将在印度推出电商服务
  10. php 源文件加密工具PHP Screw
  11. python汇总数据的程序_Python数据处理常用程序模块汇总
  12. WPF 凭证分录控件
  13. 2021世界机器人大赛— 青少年机器人设计大赛
  14. Linux下压缩mp3文件
  15. 为什么HierachyViewer无法连接真机调试
  16. Win11未识别的网络无internet怎么办?
  17. X86_64 GNU汇编、寄存器、内嵌汇编
  18. 2.3 视图的层次关系
  19. 【资源-文档】转载侵删 | STM32F10XXX参考手册(中文)
  20. Latex写论文时图片脚注的fig后冒号如何改为句号

热门文章

  1. 第7关:求解一元二次方程
  2. 想成为牛逼网页设计师吗?
  3. java web 点着点着就死掉了_Websphere(was)故障-挂死,重启,产生core.*.dmp,javacore文件-分析和解决...
  4. win10笔记本识别不到蓝牙鼠标的解决办法
  5. 12-1 蓝色天空 : 创建一个背景为蓝色的Pygame窗口 12-2 游戏角色 : 找一幅你喜欢的游戏角色位图图像或将一幅图像转换为位图。 创建一个类, 将该角色绘制到屏幕中央, 并将该图像的背景色
  6. 【助教工作】2021团队项目助教跟班全攻略
  7. java compiler类_利用 JavaCompiler 编译 Java 类文件
  8. HuaWei ❀ BGP GR与NSR
  9. 《考试脑科学》阅读笔记
  10. python飞机大战实验报告心得_Python学习之路「第七篇」-Pygame之飞机大战1