3

ベクトル計算がいっぱいのコードで次のプリプロセッサトリックを使用するのは良い習慣でしょうか?一方では、一般的な識別子(mul、add、...)を使用して名前空間を汚染し、汚いハックのようなにおいがしますが、他方では、複雑な式を読みやすくする可能性があります。他に長所/短所はありますか?

typedef struct { double x,y; } vector;
vector vector_add(vector v0, vector v1);
double vector_mul(vector v0, vector v1);
...
#define _(a) opf(a)
#define mul ,mul,
#define add ,add,
...
#define opf(a,o,b) vector_##o((a),(b))

void example(void)
{
  vector a, b, c;
  double d;

  d = _( _(a add b) mul c);

  // equivalent without the macros:
  d = vector_mul(vector_add(a,b),c);
}
4

1 に答える 1

3

いいえ、それは良い考えではありません (もちろん、私の意見では)。

C 言語をかなりよく知っていると仮定すると、次のようなコード行が表示されます。

d = vector_mul(vector_add(a,b),c);

私はそれが何をするかについてかなり良い考えを持っています。a確かに、 、bc、およびの型と関数の宣言を調べる必要がありますがd、それがなくても、ベクトルの加算とベクトルの乗算を行っていると安全に想定できます。

一方、私が見ると:

d = _( _(a add b) mul c);

最初にマクロ定義を追跡し、新しい構文を理解するまでそれらを研究するか、理解できる通常の C コードに自分で拡張するまで、それが何をしているのか見当がつかないでしょう。もちろん、あなたは自分の構文が何を意味するかを知っています。コードを読んでいるのがあなただけであればそれで問題ありませんが、他の人はアンダースコアが何のためにあるのか疑問に思うでしょう。

そして、それはあなたがマクロを使用していることを認識していると仮定しています. マクロ名は慣習的にすべて大文字で記述されます。ADDandを使用するとMUL改善されますが、IMHO は他の欠点を無効にするのに十分ではありません。

個人的な逸話: 何年も前、私が初めて C を学習したとき、私は次のように考えました。

#define EVER ;;

...

for (EVER) {
    /* ... */
}

とても賢かった。今でもとても賢いと思います。私はもはやそれが良い考えだとは思わない。

于 2012-09-27T22:33:28.147 に答える