代码之家  ›  专栏  ›  技术社区  ›  martin

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

  •  13
  • martin  · 技术社区  · 16 年前

    11 回复  |  直到 16 年前
        1
  •  16
  •   unwind    16 年前

    根据 this Wikipedia page ,在C99的stdint.h标题中 可以

    • C99型
    • 选择实现标准的这个可选部分的编译器实现程序

    所以总的来说我觉得这个很难。

        2
  •  15
  •   paxdiablo    15 年前

    简单地说,不是。不是所有的架构都能保证。

    我的问题是:为什么?如果要分配一个足够大的类型来存储 void* . 为什么需要把它放在 int ?

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

    . 不能保证1、2和3不是完全有效的指针。在需要在4字节边界上对齐指针的系统中可能会出现这种情况,但是,既然您询问了所有体系结构,我就假设您具有很高的可移植性。

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

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

    然后,可以使用isPointer“boolean”来决定是将并集视为整数还是指针。

    编辑:

    如果执行速度是最重要的,那么typedef解决方案就是最佳选择。基本上,您必须为要在其上运行的每个平台定义所需的整数。您可以通过条件编译来实现这一点。我还将添加一个运行时检查,以确保您已为每个平台正确编译,因此(我在源代码中定义了它,但您会将其作为编译器标志传递,如“ cc -DPTRINT_INT

    #include <stdio.h>
    #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\ u INT(或long)编译。也许有一种方法可以在编译时用#if捕捉到这一点,但我现在不想费心研究它。如果你碰到一个没有足够整数类型来容纳指针的平台,你就走运了。

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

        3
  •  13
  •   Pete Kirkham    16 年前

    7.18.1.4能够容纳对象指针的整数类型 以下类型指定了一个带符号整数类型,其属性是任何指向void的有效指针都可以转换为该类型,然后再转换回指向void的指针,结果将与原始指针相等:

        intptr_t
    

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

       uintptr_t
    

    C99还定义了尺寸和公差:

    类型是

      ptrdiff_t
    

      size_t
    

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

    我见过的体系结构中,对象的最大大小等于整个内存,所以sizeof(size\u t)==sizeof(void*),但我不知道有什么东西既可以移植到C89(这是 size_t 保证足够大 uintptr_t 是)。

        4
  •  4
  •   Liedman    16 年前

    这在标准32位系统上是正确的,但是肯定没有保证,而且您可以找到许多不正确的架构。例如,一个常见的误解是x86\u64上的sizeof(int)应该是8(因为我猜它是一个64位系统),而事实并非如此。在x86_64上,sizeof(int)仍然是4,但是sizeof(void*)是8。

        5
  •  2
  •   Aaron Digulla    16 年前

    在构建过程中包含此代码很简单(使用 make ,例如)

        6
  •  1
  •   Ronny Vindenes    16 年前

    intptr_t ptrdiff_t .

        7
  •  0
  •   Rob McCready    16 年前
        8
  •  0
  •   AlexDrenea    16 年前

    int数据类型将是大多数体系结构的答案。

    对此的保证

        9
  •  0
  •   Magnus Hoff    16 年前

    答案似乎是“不”,但如果您所需要的只是一个可以同时充当两者的类型,那么您可以使用union:

    union int_ptr_t {
        int i;
        void* p;
    };
    
        10
  •  0
  •   qrdl    16 年前

    所以不能保证。