0

我在库 API 中定义了一个实用程序结构,它有四个字段,都是数字计数器。

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

我应该考虑如何权衡这两种方法?每种方法都可能同样强大和灵活,但出于某种原因,一种方法是否特别可取?

4

3 回答 3

2

喜欢函数而不是宏,原因很简单,因为它们为您提供与宏不同的类型安全性。
此外,使用函数,您不必像宏那样处理任何副作用。

至于函数,inline它只是向编译器表明您希望它不绑定到编译器以生成函数inline,但是任何现代编译器都可以轻松完成所需的工作。

于 2012-04-19T16:36:26.340 回答
0

正如 Als 所说,出于维护的原因,我认为在有这种可能性时应该使用函数。由于它们是内联的,因此没有性能损失。将宏保存为常量,或者可能(非常)小的计算。

(注意:inline关键字使函数被原地替换,节省了上下文切换开销但引入了空间问题。除非您想为速度留出空间,否则您也可以使用常规函数)

于 2012-04-19T16:39:35.403 回答
0

宏在编译器范围之外(之前)被评估,这是反对这些的主要论点(这是大多数时候它们只是不必要的第二个论点)。您可以在这里找到 Bjarne Stroustrup 本人的一个很好的解释。

于 2012-04-19T17:01:24.980 回答