鉴于我需要在结构中存储“generics”指针的值并且对指向的内存本身没有兴趣,我发现将它存储为intptr_t
不是void*
语义上更正确。 问题是uintptr_t
是否更适合,并且当一个人比另一个更优先时?
它主要是一种风格论证(优化编译器可能生成相同或非常相似的代码)。 但是,指针比较可能是一个棘手的问题。
请记住,在纯粹的标准C指针比较中,仅对指向相同聚合数据的指针大致有意义。 您可能不允许比较来自malloc
两个结果,例如,保留已排序的指针数组。
我会把它们视为void*
,或者作为uintptr_t
。 签名的intptr_t
有分离负数和正数的不便,以及它们来自重要的应用程序指针,这可能不受欢迎。
请注意, void*
不能被取消引用:作为uintptr_t
,您必须将其uintptr_t
为对地址指向的数据执行有用的操作; 但是void*
指针可以传递给像memset
这样的例程
PS。 我假设一个普通的处理器(例如某些x86,PowerPC,ARM,……)具有平坦的虚拟地址空间。 您可以找到奇特的处理器 – 可能是某些DSP – 具有非常显着的差异(并且可能在其上intptr_t
并不总是有意义的;请记住在20世纪90年代Cray Y-MP超级计算机sizeof(long*) != sizeof(char*)
;在那时间C99不存在,我不确定它的
在这样的机器上是否有意义)
这听起来很奇怪,因为它需要演员阵容。 C中的void *
具有巨大的优势,它可以在没有强制转换的情况下转换为其他对象指针类型,也可以从其他对象指针类型进行转换。
也就是说uintptr_t
可能有意义,如果你想对指针的某些部分做一些你不能用有符号整数明智地做的事情(例如将它们移到右边)。
如果你想算术地操纵值(例如,加密它),你可以更灵活地使用无符号类型(算术环绕)而不是有符号类型(算术溢出给出未定义的行为)。
您应该选择适合给定系统和程序的类型。 大多数情况下,指针是正地址值,在这种情况下, uintptr_t
是正确的类型。 但是有些系统使用负地址作为表达内核空间的方式,如下所述: 指针(地址)是否可以是负数? 这就是为什么有两种不同类型的原因。
对于通用指针类型的(u)intptr_t
vs void*
,前者在粗糙的专业程序中是首选。 与指针类型相关的问题/错误源有很多:
话虽这么说,很多遗留代码依赖于void
指针,在受限制的上下文中使用它们是完全正确的。 一些例子是依赖generics回调函数的规范代码: bsearch
, qsort
,pthreads等。
但是我不建议在设计新的C程序时使用void
指针 – 在我看来,它们被认为是过去的一个危险特征。 现在存在更好更安全的通用C编程方法,例如C11 _Generic
,使用指定初始化器的技巧,将参数作为数组指针传递给VLA,使用static_assert
等在编译时进行边界检查等。一些例子可以在我的答案中找到这里: 如何创建类型安全枚举? 。
需要了解更多c/c++开发分享什么时候uintptr_t比intptr_t更受欢迎?,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!
以上就是c/c++开发分享什么时候uintptr_t比intptr_t更受欢迎?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/979866.html