From: see@... (Douglas Wells) Date: 2007-03-19T09:15:04+09:00 Subject: Re: Problem trying to use varargs in private function within C extension In article <1174230439.978761.157660@b75g2000hsg.googlegroups.com>, "Daniel Berger" writes: > Hi all, > > Ruby 1.8.6 > Windows XP > VC++ 8 > > This simple C extension complains of "too few arguments for call" when > I try to build it. Yet, within a standalone C program it works fine. > Am I forced to use varargs.h instead of stdarg.h? If so, how do I make > this work? The varargs.h docs confuse me. Let me add a few comments in addition to Patrick Hurley's correction (in <554ac39c0703180901u6db598dch277233129e509b79@mail.gmail.com>): First, varargs.h will not help. In fact, you don't even need stdarg.h until you actually start to reference the arguments using the appropriate macros. Second, turn on the compiler diagnostics. *Both* of your programs below are not legal C and any reasonable compiler should diagnose the problem(s). In particular, your declarations and definitions of "test" differ. Your declaration declares the procedure to have one mandatory argument; your definition requires that there are two mandatory arguments. These are inconsistent (and thus illegal). Third, relevant to Patrick's correction, note that your "stand-alone" test case is not at all the same as the in-context code (the number of arguments supplied is different). > #include > #include > > int test(const char*, ...); > /* String mandatory, encoding optional */ > int test(const char* str, int encoding, ...){ > int total = 0; > total = encoding; > > printf("X: %s\n", str); > printf("Encoding: %i\n", encoding); > > return total; > } Running with spirit of this comment: /* String mandatory, encoding optional */ int test(const char* x, ...){ va_list ap; int total = 0; int encoding; va_start (ap, x); encoding = va_arg(ap, int); va_end(ap); total = encoding; printf("Encoding: %i\n", encoding); return total; } > static VALUE foo_test(VALUE self){ > int total = 0; > > total = test("hello"); /* Failure! */ > printf("TOTAL: %i\n"); > return self; > } > > void Init_foo(){ > VALUE cFoo = rb_define_class("Foo", rb_cObject); > rb_define_method(cFoo, "test", foo_test, 0); > } > > And here's the standalone C code that builds and runs fine: Just because it builds and runs fine doesn't mean that it isn't wrong. That mind set just leads to future problems. > #include > #include > #include > > int test(const char*, ...); > > int main(){ > int val = 0; > > val = test("hello", 3); > printf("VAL: %i\n", val); > > return 0; > } > > int test(const char* x, int encoding, ...){ > int total = 0; > total = encoding; > > printf("Encoding: %i\n", encoding); > > return total; > } > > Dan - dmw -- . Douglas Wells . Connection Technologies . . Internet: -sp9804- -at - contek.com- .