C 为什么int*转换为void**?
我在开源EDKII代码库中看到以下代码片段: 一些背景: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
#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;
}
}