C 为什么int*转换为void**?

C 为什么int*转换为void**?,c,pointers,void,void-pointers,C,Pointers,Void,Void Pointers,我在开源EDKII代码库中看到以下代码片段: 一些背景: #define VOID void #define SPIN_LOCK_RELEASED ((UINTN) 1) #define SPIN_LOCK_ACQUIRED ((UINTN) 2) typedef volatile UINTN SPIN_LOCK; typedef unsigned __int64 UINTN; //depending on the b

我在开源EDKII代码库中看到以下代码片段:

一些背景:

#define VOID      void
#define SPIN_LOCK_RELEASED          ((UINTN) 1)
#define SPIN_LOCK_ACQUIRED          ((UINTN) 2)
typedef volatile UINTN              SPIN_LOCK;
typedef unsigned __int64    UINTN; //depending on the build options
typedef unsigned __int32    UINTN; //depending on the build options
以及

好了,处理不同的位宽是有逻辑的

对于位置A,我不知道为什么我们可以将
UINTN*
转换为
void**
。为什么要将指针显式转换为指向指针的指针

对于位置B,它是如何工作的

加1
灵感来源于@UnholySheep的评论。如果这一切归结为
sizeof(void*)
,为什么不写
SizeOfValue=(UINT8)sizeof(void*)而不是在参数
值上使用类型转换

第二个看起来像是用来确定代码是在32位还是64位系统上运行的,不是吗?(这归结为
sizeof(void*)
)你是在问为什么要知道技术原因,还是逻辑设计原因?@StoryTeller我想知道为什么可以添加另一个间接层次。我认为指针转换的间接寻址级别应该匹配。这段代码似乎假定
sizeof(UINTN)==sizeof(VOID*)
,并使用整数存储地址。在我看来,您的想法是正确的。我不知道为什么这样写。
BOOLEAN
EFIAPI
AcquireSpinLockOrFail (
  IN OUT  SPIN_LOCK                 *SpinLock
  )
{
  SPIN_LOCK   LockValue;
  VOID        *Result;

  ASSERT (SpinLock != NULL);

  LockValue = *SpinLock;
  ASSERT (LockValue == SPIN_LOCK_ACQUIRED || LockValue == SPIN_LOCK_RELEASED);

  _ReadWriteBarrier ();
  Result = InterlockedCompareExchangePointer (
             (VOID**)SpinLock, // <============= PLACE A
             (VOID*)SPIN_LOCK_RELEASED,
             (VOID*)SPIN_LOCK_ACQUIRED
           );

  _ReadWriteBarrier ();
  return (BOOLEAN) (Result == (VOID*) SPIN_LOCK_RELEASED);
}
VOID *
EFIAPI
InterlockedCompareExchangePointer (
  IN OUT  VOID                      **Value,
  IN      VOID                      *CompareValue,
  IN      VOID                      *ExchangeValue
  )
{
  UINT8  SizeOfValue;

  SizeOfValue = (UINT8) sizeof (*Value); // <=========== PLACE B

  switch (SizeOfValue) {
    case sizeof (UINT32):
      return (VOID*)(UINTN)InterlockedCompareExchange32 (
                             (UINT32*)Value,
                             (UINT32)(UINTN)CompareValue,
                             (UINT32)(UINTN)ExchangeValue
                             );
    case sizeof (UINT64):
      return (VOID*)(UINTN)InterlockedCompareExchange64 (
                             (UINT64*)Value,
                             (UINT64)(UINTN)CompareValue,
                             (UINT64)(UINTN)ExchangeValue
                             );
    default:
      ASSERT (FALSE);
      return NULL;
  }
}