0

这里有两段代码,一段是宏,一段是函数。他们似乎做同样的事情,但在运行它们之后,它们似乎表现出不同的行为,我不知道为什么。有人可以帮我吗?谢谢!

#define ROL(a, offset) ((((Lane)a) << ((offset) % LANE_BIT_SIZE)) ^ (((Lane)a) >> (LANE_BIT_SIZE-((offset) % LANE_BIT_SIZE))))

Lane rotateLeft(Lane lane, int rotateCount)
{
    return ((Lane)lane << (rotateCount % LANE_BIT_SIZE)) ^ ((Lane)lane >> (LANE_BIT_SIZE - (rotateCount % LANE_BIT_SIZE))) ;
}

注意:Lane 类型只是一个无符号整数,LANE_BIT_SIZE 是一个数字,以位数表示 Lane 的大小。

4

4 回答 4

0

将使用宏想象为将宏的主体替换为您正在使用它的位置。

例如,假设您要定义一个宏:#define quadruple(a) ((a) * (a) * (a) * (a))

...然后您将像这样使用该宏:

int main(void) {
    int x = 1;
    printf("%d\n", quadruple(x++));
}

你希望在这里发生什么?将宏替换到代码中会导致:

int main(void) {
    int x = 1;
    printf("%d\n", ((x++) * (x++) * (x++) * (x++)));
}

事实证明,这段代码使用了未定义的行为,因为它在同一个表达式中多次修改 x。那可不好!你认为这可以解释你的行为差异吗?

于 2013-03-04T05:22:04.413 回答
0

一个是宏,一个是函数,简单的理解在调用方式上有所不同。

由于函数 CONTEXT SWITCHING 将在那里,您的代码流将更改为调用函数并最终返​​回,因此与 MACRO 相比,执行延迟非常小。

除此之外不应该有任何其他区别。

请尝试将函数声明为内联函数,然后两者应该相同。

于 2013-03-04T06:30:31.413 回答
0

Lane 可以提升为具有更多位的类型,例如当它是unsigned charorunsigned short时,或者当它用于具有混合类型的更大赋值时。然后该<<操作会将较高位移动到较大类型的附加位中。

通过函数调用,这些位将被切断,因为它返回一个 Lane,而宏为您提供提升类型的完整结果,包括附加位 - 除了宏的其他问题,如参数的多次评估。

于 2013-03-04T06:45:41.503 回答
-2

这里有两段代码,一段是宏,一段是函数。他们似乎做同样的事情,但在运行它们之后,它们似乎表现出不同的行为,我不知道为什么。

不,他们正在做同样的事情。

ROL(a, offset);                          //does a*(2^offset)
rotateLeft(Lane lane, int rotateCount);  //does lane*(2^rotateCount)

唯一的区别是 ROL 是通过宏实现的,而 rotateLeft() 是一个函数。

宏和函数的区别

  • 宏在编译器的预处理阶段执行,而函数在运行时被调用时执行。
  • 结果,宏比函数执行得更快,但是当多次调用时,宏文本会冗余地替换相同的代码,并且它们最终会比使用函数的实现消耗更多的“代码”内存。
  • 与函数不同,宏中没有类型强制。
于 2013-03-04T04:29:58.550 回答