SCM_ASSERT()

#define TRL_EXECUTE(foo) (SCM_ASSERT(bar), baz)
としていたので、非 debug 時には (, baz) と展開されてしまい、error になる。他にも
#define SCM_ENCODING_ASSERT(cond) (SCM_ASSERT(cond))
も SCM_ENCODING_ASSERT(foo); が (); と展開されてしまい、error になる。

後者は空になるかもしれない macro の呼び出しは括弧で括らない (というか () 演算子の優先度は非常に高いのでそもそも要らなそげ) ようにすれば回避できるけど、前者は厄介だな。
追記: いや、優先順位の問題じゃないな。作用する phase が他の演算子と違うので、lexically juxtaposed である限り最優先で処理されるのだ。

#if ! DEBUG
SCM_ASSERT(cond) 0
#endif

とかすると今度は "statement with no effect" の警告が邪魔だし。おおそうだ、libc の assert() を見てみようということで開いてみると (void) cast がついていた。なるほどね。空っぽは本当はいけないのか…。
移植性のほどがわからんので、SCM_VOID_EXPR とでも定義するべな。

compaction support 進行中

んー、なんか色々効率悪 *そうな* 箇所があるなあ。Compiler の最適化がどれぐらい効くかで評価が思い切り変わるけど。

その1 (確実)

#define SCM_CONS_CAR_VAL(a) ((ScmObj)(SCM_CELL_CAR(a)))

Cons の tag 00 にしてる意味ないしそれ。orz

2

#define SCM_SAL_RECLAIM_CELL(cell, next)                                     \
    do {                                                                     \
        SCM_ENTYPE_FREECELL(cell);                                           \
        SCM_UNMARK(cell);                                                 \
        SCM_FREECELL_SET_NEXT((cell), (next));                               \
    } while (/* CONSTCOND */ 0)

(cell)->car = 0; (cell)->cdr = 0; かそういう操作にしないと 2 operation で済まないかも知れない。

面倒見てもらえないのか…

jun@debian /tmp
$ cat tmp.c
int f(int o)
{
  return (o & 6) == 6 && (o & 8) == 0;
}
jun@debian /tmp
$ gcc -O3 -S -o - tmp.c
        .file   "tmp.c"
        .text
        .p2align 4,,15
.globl f
        .type   f, @function
f:
        pushl   %ebp
        movl    %esp, %ebp
        movl    8(%ebp), %edx
        movl    %edx, %eax
        andl    $6, %eax        ; <---
        cmpl    $6, %eax
        je      .L9
.L2:
        popl    %ebp
        xorl    %eax, %eax
        ret
        .p2align 4,,7
.L9:
        testb   $8, %dl         ; <---
        movl    $1, %eax
        jne     .L2