0

以下に 2 つのコード スニペットを示します。1 つはマクロで、もう 1 つは関数です。それらは同じことをしているように見えますが、それらを実行した後、異なる動作を示しているようで、その理由はわかりません。誰か助けてくれませんか?ありがとう!

#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))) ;
}

注: レーン タイプは unsigned int であり、LANE_BIT_SIZE はレーンのサイズをビット数で表した数値です。

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

レーンは、より多くのビットを持つタイプに昇格される場合があります。たとえば、それが または のunsigned char場合unsigned short、または混合タイプのより大きな代入で使用される場合です。この<<操作は、上位ビットをより大きなタイプの追加ビットにシフトします。

関数呼び出しでは、レーンを返すため、これらのビットは切り捨てられますが、マクロは、追加のビットを含む昇格された型の完全な結果を提供します-引数の複数の評価などのマクロの他の問題に加えて.

于 2013-03-04T06:45:41.503 に答える
0

1 つはマクロで、もう 1 つは関数です。単純に理解すると、呼び出される方法に違いが生じます。

関数 CONTEXT SWITCHING がそこにある場合と同様に、コード フローは呼び出し関数に変更され、最終的に返されるため、MACRO と比較して実行の遅延が非常に小さくなります。

それ以外に違いはないはずです。

関数をインライン関数として宣言してみてください。両方が同じである必要があります。

于 2013-03-04T06:30:31.413 に答える
-2

以下に 2 つのコード スニペットを示します。1 つはマクロで、もう 1 つは関数です。それらは同じことをしているように見えますが、それらを実行した後、異なる動作を示しているようで、その理由はわかりません。

いいえ、彼らは同じことをしています。

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

唯一の違いは、ROL がマクロによって実装され、rotateLeft() が関数であることです。

マクロと関数の違い

  • マクロはコンパイラの前処理段階で実行されますが、関数は実行時に呼び出されると実行されます。
  • その結果、マクロは関数よりも高速に実行されますが、複数回呼び出されると、マクロ テキストが同じコードに冗長に置き換えられ、関数を使用した実装よりも多くの「コード」メモリを消費することになります。
  • function とは異なり、マクロには Type Enforcement はありません。
于 2013-03-04T04:29:58.550 に答える