当前位置:  开发笔记 > 运维 > 正文

sizeof(int)== sizeof(void*)?

如何解决《sizeof(int)==sizeof(void*)?》经验,为你挑选了3个好方法。

是否存在与指针大小相同的整数类型?所有微体系结构都保证?



1> unwind..:

根据这个维基百科页面,在C99你的stdint.h头可能会声明intptr_t和uintptr_t,但那当然需要

C99

已选择实现标准的此可选部分的编译器实现者

总的来说,我觉得这个很难.



2> paxdiablo..:

简单地说,不.并非所有架构都能保证.

我的问题是:为什么?如果你想分配一个足够大的类型来存储a void*,那么分配的最好的东西是(令人惊讶的是:-) a void*.为什么需要将其装入int

编辑:根据您对重复问题的评论,您希望存储指针(1,2,3)的特殊值以指示额外信息.

没有!!不要这样做!! .无法保证1,2和3不是完全有效的指针.在您需要在4字节边界上对齐指针的系统中可能就是这种情况,但是,由于您询问了所有体系结构,我假设您将可移植性视为高值.

找到另一种方法,这是正确的.例如,使用union(来自内存的语法,可能是错误的):

typedef struct {
    int isPointer;
    union {
        int intVal;
        void *ptrVal;
    }
} myType;

然后你可以使用isPointer'boolean'来决定是否应该将union作为整数或指针处理.

编辑:

如果执行速度至关重要,那么typedef解决方案就是最佳选择.基本上,您必须为要运行的每个平台定义所需的整数.您可以使用条件编译来完成此操作.我还会添加运行时检查以确保您已正确编译每个平台(我在源代码中定义它,但您将其作为编译器标志传递,如" cc -DPTRINT_INT"):

#include 
#define PTRINT_SHORT
#ifdef PTRINT_SHORT
    typedef short ptrint;
#endif
#ifdef PTRINT_INT
    typedef int ptrint;
#endif
#ifdef PTRINT_LONG
    typedef long ptrint;
#endif
#ifdef PTRINT_LONGLONG
    typedef long long ptrint;
#endif

int main(void) {
    if (sizeof(ptrint) != sizeof(void*)) {
        printf ("ERROR: ptrint doesn't match void* for this platform.\n");
        printf ("   sizeof(void*    ) = %d\n", sizeof(void*));
        printf ("   sizeof(ptrint   ) = %d\n", sizeof(ptrint));
        printf ("   =================\n");
        printf ("   sizeof(void*    ) = %d\n", sizeof(void*));
        printf ("   sizeof(short    ) = %d\n", sizeof(short));
        printf ("   sizeof(int      ) = %d\n", sizeof(int));
        printf ("   sizeof(long     ) = %d\n", sizeof(long));
        printf ("   sizeof(long long) = %d\n", sizeof(long long));
        return 1;
    }

    /* rest of your code here */

    return 0;
}

在我的系统(Ubuntu 8.04,32位)上,我得到:

ERROR: ptrint typedef doesn't match void* for this platform.
   sizeof(void*    ) = 4
   sizeof(ptrint   ) = 2
   =================
   sizeof(short    ) = 2
   sizeof(int      ) = 4
   sizeof(long     ) = 4
   sizeof(long long) = 8

在那种情况下,我知道我需要使用PTRINT_INT(或long)进行编译.可能有一种方法可以在编译时使用#if来捕获它,但我现在无法对它进行研究.如果你敲击一个没有足以容纳指针的整数类型的平台,那你就不走运了.

请记住,使用特殊指针值(1,2,3)表示整数也可能不适用于所有平台 - 这实际上可能是指针的有效内存地址.

不过,如果你不理会我的建议,那么我无能为力阻止你.毕竟这是你的代码:-).一种可能性是检查malloc中的所有返回值,如果得到1,2或3,则再次使用malloc(即,使用mymalloc()自动执行此操作).这将是一个小的内存泄漏,但它会保证你的特殊指针和真正的指针之间没有冲突.



3> Pete Kirkham..:

C99标准定义了标准的int类型:

7.18.1.4能够保存对象指针的整数类型以下类型指定一个有符号整数类型,其属性是任何有效的指向void的指针都可以转换为此类型,然后转换回指向void的指针,结果将比较等于原始指针:

    intptr_t

以下类型指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针:

   uintptr_t

这些类型是可选的.

C99还定义了size_t和ptrdiff_t:

类型是

  ptrdiff_t

这是减去两个指针的结果的有符号整数类型;

  size_t

这是sizeof运算符的结果的无符号整数类型; 和

我见过的体系结构的对象最大大小等于整个内存,所以sizeof(size_t)== sizeof(void*),但我不知道任何可以移植到C89的东西(也就是说size_t)并保证足够大(这uintptr_t是).

推荐阅读
mobiledu2402852357
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有