0

ライブラリAPIで定義されたユーティリティ構造体があり、4つのフィールド、すべて数値カウンターがあります。

typedef struct {
  size_t bytes;
  int    codepoints;
  int    graphemes;
  int    columns;
} TickitStringPos;

これらの構造を簡単に操作できるユーティリティをいくつか提供したいと思います。これらを(静的インライン)関数として実装できます。

static inline void tickit_stringpos_zero(TickitStringPos *pos) {
  pos->bytes = pos->codepoints = pos->graphemes = pos->columns = 0;
}

static inline void tickit_stringpos_limit_columns(TickitStringPos *pos, int columns) {
  pos->bytes = pos->codepoints = pos->graphemes = -1;
  pos->columns = columns;
}

TickitStringPos here, limit;
tickit_stringpos_zero(&here);
tickit_stringpos_limit_columns(&limit, 20);

または、これらをマクロとして実装することもできます。

#define TICKIT_STRINGPOS_ZERO(pos) do { \
  (pos).bytes = (pos).codepoints = (pos).graphemes = (pos).columns = 0; \
} while(0);

#define TICKIT_STRINGPOS_LIMIT_COLUMNS(pos,_columns) do { \
  (pos).bytes = (pos).codepoints = (pos).graphemes = -1; \
  (pos).columns = _columns; \
} while(0);

TickitStringPos here, limit;
TICKIT_STRINGPOS_ZERO(here);
TICKIT_STRINGPOS_LIMIT_COLUMNS(limit, 20);

これら2つのアプローチを比較検討するために何を検討する必要がありますか?それぞれが同じように強力で柔軟性がある可能性がありますが、何らかの理由で1つのアプローチが特に望ましいのでしょうか。

4

3 に答える 3

2

関数は、マクロとは異なり、型の安全性を提供するという単純な理由で、マクロよりも優先されます。
また、関数を使用すると、マクロのように副作用を気にする必要がありません。

関数については、関数inlineを作成するためにコンパイラにバインドされていないことをコンパイラに示すだけですが、inline最新のコンパイラは必要なことを簡単に実行します。

于 2012-04-19T16:36:26.340 に答える
0

Als が言ったように、保守上の理由から、そのような可能性がある場合は関数を使用する必要があると思います.関数はインラインであるため、パフォーマンスの低下はありません.定数または (非常に) 小さい計算のためにマクロを保存します.

(注: inlineキーワードを使用すると、関数がその場で置き換えられ、コンテキスト切り替えのオーバーヘッドが節約されますが、スペースの問題が発生します。速度のためにスペースを確保したい場合を除き、通常の関数を使用することもできます)

于 2012-04-19T16:39:35.403 に答える
0

マクロはコンパイラのスコープ外 (前) で評価され、これがそれらに対する主な議論です (ほとんどの場合、マクロは不要であるという 2 番目の議論です)。ここでは、Bjarne Stroustrup 自身による適切な説明を見つけることができます。

于 2012-04-19T17:01:24.980 に答える