将目标内存地址作为 uint32_t 传递给 memcpy 会引发警告

Passing the destination memory address as a uint32_t to memcpy throws warning

我目前正在编写一个涉及大量内存地址算术的内核,并且在 memcpy 上收到以下臭名昭著的警告:

warning: passing argument 1 of 'memcpy' makes pointer from integer without a cast
   memcpy(dest, &bf, 16*sizeof(uint32_t));

当我执行以下操作时抛出警告的示例

uint32_t bf[16];

uint32_t shmem = (uint32_t)&tos_shared;
uint32_t dest = shmem - 16*sizeof(uint32_t);
memcpy(dest, &bf, 16*sizeof(uint32_t));

其中&tos_shared (0x700347a8)是栈顶内存地址。我将它转换为 uint32_t (1879263144),这样我就可以进行算术运算并获得所需的目标地址 dest (1879262952)

如何将 dest 转换为指针但保留目标地址以便 memcpy 不报错并将 bf 放在同一个位置?值得一提的是这段代码功能很好...

使用 char*&tos_shared 会得到正确的结果。您也可以使用 sizeof bf 来简化一点。

uint32_t bf[16];

char* shmem = (char*)&tos_shared;
void* dest = shmem - sizeof bf; // sizeof bf == sizeof(uint32_t) * 16
memcpy(dest, &bf, sizeof bf);

如果您确实需要以整数类型存储指针(无论如何都应该避免),正确的类型是 uintptr_t

您需要转换回指针类型才能调用 memcpychar *void * 均可;void * 在这里更为惯用)。您还需要使用 uintptr_t 而不是 uint32_t.

进行手动指针运算
uint32_t bf[16];

uintptr_t shmem = (uintptr_t)&tos_shared;
uintptr_t dest = shmem - 16*sizeof(uint32_t);
memcpy((void *)dest, &bf, 16*sizeof(uint32_t));

不保证此代码普遍适用。但是,它是否有效是 implementation-defined,并且由于您正在编写内核,因此您 实现的(一部分),因此您可以决定是的,布局物理 RAM 的数量将始终有效。

根据你的 ABI,uint32_tuintptr_t 可能是也可能不是相同的基本类型,但你仍然应该使用 uintptr_t 即使它们是,因为那更 self-documenting 并且将来会更容易进入 64 位(假设这是您可能想要的)。