in reply to Re^2: Passing undef to XSUB
in thread Passing undef to XSUB

Would int* also work?

No, but int would:
int foo(ap,bp) int ap int bp PREINIT: int a, b; CODE: a = ap ? ap : -1; b = bp ? bp : -1; RETVAL = a * b; OUTPUT: RETVAL
Though, if warnings are enabled, that produces a "Use of uninitialized value in subroutine entry..." for each undef that's passed to it - no such warning with educated_foo's rendition.

Cheers,
Rob

Replies are listed 'Best First'.
Re^4: Passing undef to XSUB
by ikegami (Patriarch) on May 08, 2008 at 05:00 UTC
    It (presumably) compiles and runs, but I wouldn't say it works. Not only does it introduce a warning, it gives incorrect results for arguments equal to zero.
      it gives incorrect results for arguments equal to zero

      Yes ... I had missed the important point that 0 ought to be evaluated as 0 (and not -1).

      Now I understand what your speculative code was driving at.

      Cheers,
      Rob
Re^4: Passing undef to XSUB
by kyle (Abbot) on May 08, 2008 at 04:39 UTC

    I don't know much about XS, but I wonder if this code is able to distinguish between when it's passed undef and when it's passed 0. That is, can it see the difference between foo( undef, undef ) and foo( 0, 0 )? It seems to me the "uninitialized value" warning is undef getting turned into 0.

      It seems to me the "uninitialized value" warning is undef getting turned into 0

      Yes, I think that's right:
      use warnings; use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'EOC'; void foo(int a) {} void bar(SV * a) {} void baz(SV * a) { int i = (int)SvIV(a); } EOC $u = undef; foo($u); # warning bar($u); # no warning baz($u); # warning
      Cheers,
      Rob