PRIu64与intptr_t在不同架构处理器可移植性的作用

1 前言

当项目中需要将原来32位架构处理器的代码移植到ARM64架构处理器上时,在编译过程中会遇到许多的warning,这些警告大多与指针与整型变量的类型转换和printf函数参数的数据类型不相符有关。而intptr_t类型和PRIu64这些宏定义提高了代码在不同架构平台的可移植性。

2 intptr_t类型

intptr_tuintptr_t 类型用来存放指针地址。它们提供了一种可移植且安全的方法声明指针,而且和系统中使用的指针长度相同,对于把指针转化成整数形式来说很有用,这两个数据类型是ISO C99定义的,具体代码在linux平台的/usr/include/stdint.h头文件中

/* Types for `void *' pointers.  */
#if __WORDSIZE == 64
#ifndef __intptr_t_defined
typedef long int  intptr_t;
#define __intptr_t_defined
#endif
typedef unsigned long int uintptr_t;
#else
#ifndef __intptr_t_defined
typedef int   intptr_t;
#define __intptr_t_defined
#endif
typedef unsigned int  uintptr_t;
#endif

这样定义的原因是因为不同的数据类型在不同字长机器上长度大小是不同的:

machinecharshortintlongptr
161byte2byte2byte4byte2byte
321byte2byte4byte4byte4byte
641byte2byte4byte8byte8byte

指针在32位平台和64位平台下均与long类型的长度一致,然而在16位机器上,long为4个字节,而指针为2个字节。
因此,就可以发现intptr_tuintptr_t定义的巧妙之处:
在64位机器上,intptr_tlong intuintptr_tunsigned long int。而在非64位机器上,intptr_tintuintptr_tunsigned int
这样就可以保证intptr_tuintptr_t的长度与机器的指针长度一致,因此在进行整数与指针的相互转换时可以用intptr_t保证可移植性。
以下面这段代码为例:

#include <stdio.h>
#include <stdint.h>
int main()
{
	int a = 12345;    
    int *p = &a;
    int ptr = (int )p;
    printf("%d\n",ptr);  
    printf("sizeof(ptr):%ld,sizeof(p):%ld\n",sizeof(ptr),sizeof(p));
    return 0;
}

在编译时,GCC会给出warning,Wpointer-to-int-cast 表明将指针转换为整型,但是二者大小不同

test.c: In function ‘main’:
test.c:13:12: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   13 |  int ptr = (int)p;
      |            ^

如果使用uintptr_t改写代码则不会警告:

#include <stdio.h>
#include <stdint.h>
int main()

{
	uintptr_t a = 12345;
    uintptr_t *p = (uintptr_t*)a;
    printf("%p\n",p)
    printf("sizeof(a):%ld,sizeof(p):%ld\n",sizeof(a),sizeof(p));
   	return 0;
}

3 PRIu64

如下这段代码,在32位处理器和64位处理器下编译的警告会不同:

uint64_t a = 0x1234;
uint8_t str[20] = {0};
sprintf(str, "%llu", a);

使用 64 位编译器,编译报警告:uint64_tlong unsigned int 类型,请使用 "%ld"
如果改成 “%ld”,使用 32 位机器编译时,又报警告:uint64_tlong long unsigned int类型,请使用 "%lld"
这是因为在 32 位平台上,std::uint64_t将被定义为 unsigned long long并且格式说明符将为%llu。而在 64 位平台上,std::uint64_t将被定义为 unsigned long并且格式说明符将为 %lu 。
由此可见对于uint64_tint64_t这类数据类型,在sprintfprintf这类函数中的可移植性很差,是因为64位数据类型在不同架构的处理器中定义是不同的。
通过PRIu64PRId64PRIx64等宏可以很好的解决这个问题。
PRIu64 的定义在 inttypes.h 头文件中,使用时需要引入该头文件

# if __WORDSIZE == 64
# define __PRI64_PREFIX	"l"
# else
# define __PRI64_PREFIX	"ll"
# endif
# define PRIu64 __PRI64_PREFIX "u"

对于32 位编译器,会把 "%" PRIu64 "" 扩展为 "%lld",对于64 位编译器,会把 "%" PRIu64 "" 扩展为 "%ld"
示例代码如下:

#include <stdio.h>
#include <inttypes.h>

int main(int argc, char *argv[])
{
    uint64_t u64 = 100;
    int64_t  int64 = 100;
    printf("uint64: %" PRIu64 "\n", u64);
    printf("uint64 hex: %0x" PRIx64 "\n", u64);
    printf("int64: %" PRId64 "\n", int64);
    return 0;
}

注意: 如果是C++程序,需要定义_STDC_FORMAT_MACROS宏,可以在cmakelist.txt中加入add_compile_definitions(_STDC_FORMAT_MACROS)添加该宏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/611510.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【MySQL基本查询(下)】

文章目录 一、update案例 二、Delete案例注意&#xff1a;delete 全表数据的行为慎用&#xff01;truncate 三、插入查询结果案例 四、了解一些函数1.count函数2.sum函数3. avg函数4.max函数5. min函数 五、group by子句的使用案例having和where 一、update 该关键字的功能就是…

k8s遇到的常见问题及解决

1. error: open /var/lib/kubelet/config.yaml: no such file or directory 解决&#xff1a;关键文件缺失&#xff0c;多发生于没有做 kubeadm init就运行了systemctl start kubelet。 要先成功运行kubeadm init 2. 执行初始化kubeadm init ------的时候报错 The HTTP call…

(Mac)RocketMQ的本地安装测试(详细图示)

目录 部署服务 namesrv / broker下载解压缩运行 namesrvnohup ./bin/mqnamesrv & 启动命令详解运行 broker 测试收发消息运行自带的生产者测试类运行自带的消费者测试类 部署 Dashboard 可视化下载打包运行访问 部署服务 namesrv / broker 下载解压缩 官网下载 https://r…

Excel——项目管理,设置时间到期自动提醒及颜色高亮

效果图 第一步、自动获取合同到期日期 1、首先合同【签约日期】和【到期日期】下面的数据必须是日期格式&#xff0c;不能是其它的格式否则无法计算&#xff0c;如果是其它格式需要转换成标准的日期格式&#xff0c;如下图所示。 2、在“到期日期”下面的第一个单元格中输入公…

7 系列 FPGA 产品介绍及选型

目录 Spartan-7 FPGAsArtix-7 FPGAsKintex-7 FPGAsVirtex-7 FPGAsFPGA芯片命名规则DSP资源BRAM资源Transceivers 资源Transceivers 总带宽I/O 个数及带宽参考文档 Spartan-7 FPGAs Artix-7 FPGAs Kintex-7 FPGAs Virtex-7 FPGAs FPGA芯片命名规则 DSP资源 BRAM资源 Transceiver…

快速上手prometheaus grafana 监控

介绍 prometheaus 一个定时输出指标数据的巡检组件&#xff1f; grafana 一个读取指标&#xff0c;可视化的提供了好看界面的组件&#xff1f; 教程 如何和springboot项目集成 【IT老齐153】超级实用&#xff01;十分钟掌握Prometheus与Grafana监控SpringBoot应用_哔哩哔哩_…

100000订单直接拒掉,君子爱财,取之有道

近一个月询盘可谓寥寥无几&#xff0c;成交率为0&#xff0c;今天好不容易接了一个客户询盘&#xff0c;订单总价高达100000&#xff0c;听完细节直接拒掉&#xff0c;至于原因懂的都懂&#xff0c;不懂得等我慢慢道来。 前两天有2个询盘&#xff0c;其中一个是二次开发&#x…

【Python爬虫实战入门】:教你一个程序实现PPT模版自由

文章目录 &#x1f4a5;一、PPT模版爬取&#x1f525;1.1 第一个爬虫&#x1f6b2;1. 获取下载页面链接 ❤️1.2 第二个爬虫&#x1f6b2;1.3 第三个爬虫&#x1f388;2. 文件保存 ❤️1.4 翻页处理 &#x1f525;二、完整代码 &#x1f525;&#x1f525;&#x1f525; Pytho…

大腾智能网站正式上线

4月30日&#xff0c;我们翘首以盼的时刻终于来临&#xff0c;大腾智能官网&#xff08;www.da-teng.com&#xff09;正式上线&#xff0c;我们对此感到无比兴奋和自豪&#xff01;此刻&#xff0c;我们诚挚地邀请每一位朋友&#xff0c;共同踏上这个全新的数字之旅&#xff0c;…

从需求到实现的关键

版本封面 内容&#xff1a;产品logo&#xff0c;项目名称&#xff0c;所属公司&#xff0c;产品名称&#xff0c;文档类型&#xff0c;版本号&#xff0c;时间&#xff0c;相关人员&#xff08;最好说明下负责人&#xff09;。 作用&#xff1a; 突出重要信息&#xff0c;将…

【软考高项】三十八、风险管理7个过程

一、规划风险管理 1、定义、作用 定义&#xff1a;定义如何实施项目风险管理活动的过程作用&#xff1a;确保风险管理的水平、方法和可见度与项目风险程度相匹配&#xff0c;与对组织和其他干系人的重要程度相匹配 2、输入 项目管理计划 项目章程 项目文件 干系人登记册…

debian10 (armbian) 配置CUPS 服务

更新apt apt-update安装相关软件 apt-get install ghostscript apt-get install dc apt-get install foomatic-db-engine apt-get install cups3.修改配置文件 nano /etc/cups/cupsd.conf Listen localhost:631改为 Listen 0.0.0.0:631 以下四段配置加入Allow All # Only li…

中国地面气候资料日值数据获取方式

数据简介 环境气象数据服务平台提供了全国大约2100个点位&#xff0c;2000年至2023年的逐日数据。包括气温、气压、湿度、风、降水等要素。 数据基于ECMWF reanalysis-era5-land、reanalysis-era5-single-levels 以及中国2100站点地面气候资料日值观测数据&#xff0c;使用机器…

GAMMA Lab——知识图谱和LLM大模型

图机器学习的发展与分类 图基础模型 LLM基础模型 GNN LLM 前沿工作

Box86源码解读记录

1. 背景说明 Github地址&#xff1a;https://github.com/ptitSeb/box86 官方推荐的视频教程&#xff1a;Box86/Box64视频教程网盘 2. 程序执行主体图 Box86版本: Box86 with Dynarec v0.3.4 主函数会执行一大堆的初始化工作&#xff0c;包括但不限于&#xff1a;BOX上下文 …

Golang面向对象编程(一)

文章目录 结构体基本介绍结构体定义方式创建结构体变量结构体内存对齐结构体类型转换字段的Tag标签 方法基本介绍方法的定义和调用方法调用的传参机制String方法 结构体 基本介绍 基本介绍 Go支持面向对象编程特性&#xff0c;包括封装、继承和多态&#xff0c;但Go中没有类&a…

技术创作者在千帆AppBuilder中获得的极致体验

目录 前言 千帆AppBuilder简介 传统的技术文章写作方式 借助千帆AppBuilder提高写作质量和效率 千帆AppBuilder详细搭建步骤 1、注册百度智能云账号 2、登录百度智能云控制台 3、创建千帆AppBuilder应用 4、配置千帆AppBuilder应用 5、调试和发布千帆AppBuilder应用 …

文章分享:《肿瘤DNA甲基化标志物检测及临床应用专家共识(2024版)》

本文摘自于《肿瘤DNA甲基化标志物检测及临床应用专家共识&#xff08;2024版&#xff09;》 目录 1. DNA甲基化标志物概述 2 DNA甲基化标志物的临床检测 2.1 临床样本前处理注意事项 2.2 DNA甲基化标志物检测技术方法 2.2.1 DNA提取与纯化 2.2.2 DNA转化 2.2.3 DNA 甲基…

综述列表(~2024.05.10)

&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 每周末更新&#xff0c;完整版进群获取。 Q 群在群文件&#xff0c;VX 群每周末更新。

day5Qt作业

服务器端 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//准备组件&#xff0c;初始化组件状态this->setFixedSize(800,600);chatwidget new QListWidge…
最新文章