[英]Argument of type uint64_t is incompatible with parameter of type void*
我有一個函數 foo(void* pBuf)。 我需要向它傳遞一個 64 位地址,但是當我通過值傳遞時,我似乎無法獲得正確的類型轉換。
示例:foo(地址)。 其中- uint64_t 地址=0x00000000DEADBEEF
編輯:使用 ARM 編譯器進行編譯。
uint64_t foo(void *pBuf){
uint64_t retAddr = (uint64_t) pBuf;
retAddr += 0x100000;
return retAddr;
}
我在 32 位 ARM 上並且sizeof(void *)
是4
說明:為什么我在 32 位 ARM 上需要 64 位地址? 因為我的內存映射使用 36 位尋址。
這樣稱呼:
uint64_t address = 0xDEADBEEF;
foo((void*)address);
也就是說,你投的地址為void指針要與函數簽名不兼容。
您不應為地址使用64位類型,因為對於32位(或任何非64位)系統,這是未定義的行為。
相反,更喜歡使用標准C的uintptr_t
。有關更多詳細信息,請參uintptr_t
問題 ;有關參考,請參見本頁 。
那么一個解決方案可能是:
uintptr_t address = 0xDEADBEEF; /* will trigger a warning if the constant is > max possible memory size */
foo((void*)address);
注意:如果uintptr_t
在您的系統上不可用,則size_t
通常是不錯的第二選擇。
看起來,在您改寫的問題中,您想要將地址轉換為64位整數。
在這種情況下,由於寬度上的潛在差異,從ptr直接轉換為整數很可能會觸發編譯器警告。
最好使用double uint64_t value = (uint64_t)(size_t) ptr;
: uint64_t value = (uint64_t)(size_t) ptr;
我可以想到兩種方法來解決這個問題。 通過第一種方法調用foo來解決我的問題
這僅起作用是因為我對foo的輸入始終是32位值。 返回的值可以是64位。
感謝所有的建議!
很抱歉解決這個問題,但這些答案對我來說似乎都不合理。 這是一個相當簡單的類型轉換問題。 似乎人們在 32 位系統上陷入了 64 位尋址,而這很容易用於外圍設備或除系統本身之外的其他一些地址空間。
在 OP 的情況下,直接轉換為uint64_t
會導致未定義的行為,因為void *
不存在額外的四個字節。 在 M4 調用約定的情況下, p
通常會在單個寄存器中傳遞,可能是r0
。 uint64_t
沒有額外的高位字節作為別名,因此您的編譯器正確地為此發出警告。
在 GCC 7.3 arm-none-eabi
端口下, void *
可以安全地轉換為size_t
(又名unsigned int
),因為它們的大小和對齊方式都是4
。 完成后,您可以通過賦值安全地將unsigned int
提升為uint64_t
(又名unsigned long long int
)。 提升是比演員更明確的行為。
uint64_t foo(void *p){
uint64_t a = (size_t) p;
a += 0x100000;
return a;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.