わさっきhb

大学(教育研究)とか ,親馬鹿とか,和歌山とか,とか,とか.

続・関数形式マクロは演算子を引数に取れる

関数形式マクロは演算子を引数に取れる - わさっきの続き.

#include <stdio.h>

#define op(x, y, z) ((x) y (z))
#define p2(x, y) printf(#x " = %d, " #y " = %d\n", x, y)
#define opp(x, y, z) p2(x, z),\
    printf(#x " " #y " " #z " = %d\n", op(x, y, z)),\
    p2(x, z), puts("")

int main(void)
{
  int a = 4, b = 2;
  /* opp(a, ------, b); */
  /* opp(a, -----+, b); */
  /* opp(a, ----+-, b); */
  /* opp(a, ----++, b); */
  opp(a, ---+--, b);
  opp(a, ---+-+, b);
  /* opp(a, ---++-, b); */
  /* opp(a, ---+++, b); */
  /* opp(a, --+---, b); */
  /* opp(a, --+--+, b); */
  opp(a, --+-+-, b);
  opp(a, --+-++, b);
  /* opp(a, --++--, b); */
  /* opp(a, --++-+, b); */
  /* opp(a, --+++-, b); */
  /* opp(a, --++++, b); */
  /* opp(a, -+----, b); */
  /* opp(a, -+---+, b); */
  /* opp(a, -+--+-, b); */
  /* opp(a, -+--++, b); */
  opp(a, -+-+--, b);
  opp(a, -+-+-+, b);
  /* opp(a, -+-++-, b); */
  /* opp(a, -+-+++, b); */
  /* opp(a, -++---, b); */
  /* opp(a, -++--+, b); */
  opp(a, -++-+-, b);
  /* opp(a, -++-++, b); */
  /* opp(a, -+++--, b); */
  /* opp(a, -+++-+, b); */
  /* opp(a, -++++-, b); */
  /* opp(a, -+++++, b); */
  /* opp(a, +-----, b); */
  /* opp(a, +----+, b); */
  opp(a, +---+-, b);
  /* opp(a, +---++, b); */
  /* opp(a, +--+--, b); */
  /* opp(a, +--+-+, b); */
  /* opp(a, +--++-, b); */
  /* opp(a, +--+++, b); */
  /* opp(a, +-+---, b); */
  /* opp(a, +-+--+, b); */
  opp(a, +-+-+-, b);
  opp(a, +-+-++, b);
  /* opp(a, +-++--, b); */
  /* opp(a, +-++-+, b); */
  /* opp(a, +-+++-, b); */
  /* opp(a, +-++++, b); */
  /* opp(a, ++----, b); */
  /* opp(a, ++---+, b); */
  /* opp(a, ++--+-, b); */
  /* opp(a, ++--++, b); */
  opp(a, ++-+--, b);
  opp(a, ++-+-+, b);
  /* opp(a, ++-++-, b); */
  /* opp(a, ++-+++, b); */
  /* opp(a, +++---, b); */
  /* opp(a, +++--+, b); */
  opp(a, +++-+-, b);
  opp(a, +++-++, b);
  /* opp(a, ++++--, b); */
  /* opp(a, ++++-+, b); */
  /* opp(a, +++++-, b); */
  /* opp(a, ++++++, b); */

  return 0;
}

「opp(a, ---+--, b);」を展開すると,中に「a ---+-- b」という式ができますが,これは「(a--) - (+(--b))」と解釈されます.
+と-の組み合わせが4文字については,『Lepton先生のCの強化書 (開発の現場セレクション)』にありますので,ここでは6文字でやってみました.
上のプログラムでは,インクリメントやデクリメントによって,a,bの値が変わりますが,最終的には元に戻ります.+と-を組み合わせた式が正しければ,その+と-を入れ替えても正しい式になるという,「双対性」のためです.
手作業で全パターン生成・確認というのは無謀というもので,実際には生成プログラムをRubyで書きました.日を改めて,公開します.