在C宏中执行算术

时间:2018-06-25 13:07:36

标签: c linux pointers

在移植库时,我遇到以下问题。有一个与硬件等效的宏定义-

#define PREFETCH(addr) HW_PREFETCH((const volatile void *)addr)

我需要将另一个宏PREFETCH_ADDR_OFF(addr,offset)移植到HW_PREFETCH(addr)。我尝试了以下操作,但没有起作用。有没有办法在c宏内执行算术运算?

#define PREFETCH_ADDR_OFF(addr,offset) PREFETCH(addr+offset)

以下是编译错误:

  

算术中使用的“ void *”类型的指针

编辑- 这是对我有用的东西-

#define PREFETCH(addr) HW_PREFETCH(addr)
#define PREFETCH_ADDR_OFF(addr,offset) PREFETCH((((char*)addr)+offset))

3 个答案:

答案 0 :(得分:3)

addr的类型为void*,正如编译器所说,您不能对void*进行数学运算。

使用TypeCast将指针强制转换为字节指针,然后对此进行数学运算。 结果将是一个char*,应该可以自由转换为void*

#define PREFETCH_ADDR_OFF(addr,offset) PREFETCH((((char*)addr)+offset))

答案 1 :(得分:2)

偏移量指的是多少?如果它们是字节,则需要使用(char *)。如果它们是int,则应使用(int *)。指针算术将指针增加所需的数量,以逐步超过指针指向的对象。您不能使用void *。不起作用。 (void *)告诉编译器其通用指针。在将指针用于访问数据或执行指针算术之前,通常将(void *)强制转换为所需类型的指针。

基本上,“宏”只是文本替换。如果您真的卡住了,那么可以使用save-temps在替换之后但在编译之前查看文件。

答案 2 :(得分:1)

如前所述,您无法在void*上进行指针算术运算,它与宏无关,但与C标准和常识无关。 void对象有多大?

因此,您必须将其强制转换为您可以 进行算术运算的类型,

#include <stdint.h>
#define PREFETCH_ADDR_OFF(addr,offset) PREFETCH( (uintptr_t)(addr) + (offset) )