std.c.stdarg

とおもったらニュースグループにそのものずばりの記事があったよ。

std.c.stdargってなに?ってこれ0.88でPhobosに追加されたのか。知らないよ。

だがこれうまく動かせない。とりあえず記事に投稿されているものはちゃんと動作する。しかし、別モジュールのテンプレートを組み合わせたクラス内で利用して、インスタンス化しようとすると、なぜかリンカがエラーを吐く。たとえば、foo.dとして、

private import std.c.stdarg;

public class Foo(T) {
  int foo(char *x, ...) {
    va_list ap;
    va_start!(typeof(x))(ap, x);
    printf("&x = %p, ap = %p\n", &x, ap);
    T i;
    i = va_arg!(typeof(i))(ap);
    printf("i = %d\n", i);
    long l;
    l = va_arg!(typeof(l))(ap);
    printf("l = %lld\n", l);
    uint k;
    k = va_arg!(typeof(k))(ap);
    printf("k = %u\n", k);
    va_end(ap);
    return i + l + k;
  }
}

としておき、これをインスタンス化するbar.dを、

private import foo;

void main() {
  int j;
  Foo!(int) foo = new Foo!(int);
  j = foo.foo("hello", 3, 23L, 4);
  printf("j = %d\n", j);
  assert(j == 30);
}

とすると、bar.objで'Symbol Undefined'とリンカが文句を言う。ちなみにfoo.d内で'alias Foo!(int) Fooint'のようにエイリアスしてしまうと文句は言わなくなる。要するに別モジュールでテンプレートを解決しようとすると怒るらしい。

stdarg.d自体もテンプレートで動作を実現しているので、この辺で何かが衝突してるのかなあ。やっぱりテンプレートよく分からないよ...