C宏函数具有相同的正常函数输出,但算法具有不同的输出

时间:2018-04-23 20:34:04

标签: c macros

所以我有一个与宏函数定义相同的函数,它们输出相同的值。为了证实这一点,我这样做了:

int a(int vertex, int offset) {
      int value = vertex*numberOfoffsets + offset;
      if (value != b(vertex, offset)) printf("error\n");
      return value;
}

这是宏:

#define b(vertex, offset) (vertex*numberOfoffsets + offset)  //EDIT: I had mta instead of b here (on the stackoverflow post)

请注意,numberOfOffsets也是一个宏,它返回6。 我使用a(vertex,offset)运行算法,一切都按预期工作,没有打印error\n,这意味着两个函数都返回相同的值。

但是当我使用b(vertex,offset)而不是a(vertex,offset)运行算法时,会出现错误的答案(尽管算法不会中断。

关于宏,我有什么遗漏吗?他们不只是替换文字吗?我真的不明白这种行为。

编辑:抱歉,我忘了更改功能名称,b现在正确(这是定义功能)

EDIT2:添加括号可以解决问题,因此它应该是:

#define b(vertex, offset) (((vertex)*(numberOfoffsets)) + (offset))

但是其他用户建议我使用内联函数,所以现在是:

static __inline__
int b(int vertex, int offset) {
  return vertex*numberOfoffsets + offset;
}

1 个答案:

答案 0 :(得分:4)

通常,您应该在宏定义中使用过多的括号,例如:

#define b(vertex, offset) ((vertex) * 6 + (offset))

否则,运算符优先级可以将结果更改为意外的内容。例如,使用

调用宏
int x = 4;
int y = b(x+1, 3);

应与y = 5 * 6 + 3 = 33相同。但是,如果没有括号,结果为
 y = 4 + 1*6 + 3 = 13

评论中指出的@jxh与宏和函数之间还有另一个区别。

当调用带有int参数的函数且参数不是int类型的函数时,编译器将隐式地将参数转换为int。但是使用宏,没有进行这样的转换。

例如,代码

#define b(vertex, offset) ((vertex) * 6 + (offset))

int a(int vertex, int offset)
{
    return vertex * 6 + offset;
}

int main(void)
{
    double vertex = 3.3;
    double offset = 7.4;
    int resultA = a(vertex, offset);
    int resultB = b(vertex, offset);
    printf("%d %d\n", resultA, resultB);
}

将打印25 27。这是因为编译器在调用函数之前将vertex转换为3并将offset转换为7。但宏使用double值进行数学计算,并且通过赋值给int将答案转换为resultB

你是否需要对此做任何事情都值得商榷。但是,要使宏完全等效于函数,可以将其写为

#define b(vertex, offset) ((int)((int)(vertex) * 6 + (int)(offset)))