这2个代码片段的区别

时间:2013-03-04 04:10:11

标签: c

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

#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类型只是一个unsigned int,而LANE_BIT_SIZE是一个以位数表示Lane大小的数字。

4 个答案:

答案 0 :(得分: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。那不好!你认为这可以解释你的行为差异吗?

答案 1 :(得分:0)

一个是宏,另一个是函数,简单的理解给出了调用方式的不同。

在函数CONTEXT SWITCHING的情况下,您的代码流将更改为调用函数并最终返​​回,因此与MACRO相比,执行时会有非常小的延迟。

除此之外不应该有任何其他差异。

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:-2)

  

以下是2个代码片段,一个是宏,一个是函数。   他们似乎做了同样的事情,但在运行它们之后似乎就是这样   他们表现出不同的行为,我不知道为什么。

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

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

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

宏和函数之间的差异

  • 宏在编译器的预处理阶段执行, 而函数在运行时执行时被执行。
  • 因此,宏执行速度比函数快,但调用时 多次,宏文本冗余地替换相同的代码,并且它们最终消耗比使用函数的实现更多的“代码”内存。
  • 与函数不同,宏中没有Type Enforcement。