in reply to Passing undef to XSUB

The wrapper's easier and probably better (e.g. it's easy to support keyword parameters), but you can also take raw SVs in your XS code, like so:
int foo(a,b) SV * a SV * b PREINIT: int aa, bb; CODE: aa = SvIOK(a) ? SvIV(a) : -1; bb = SvIOK(b) ? SvIV(b) : -1; RETVAL = aa * bb; OUTPUT: RETVAL

Replies are listed 'Best First'.
Re^2: Passing undef to XSUB
by ikegami (Patriarch) on May 07, 2008 at 22:50 UTC
    Would int* also work? Like in
    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
      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
        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.

        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.

      Not for me -- int* doesn't appear to have a typemap for me (perl 5.8.8).
        Thanks