On May 18, 2007, at 2:58 AM, Xavier Noria wrote:
OK, I've got something. Very misterious!!!
Fortunately the segmentation fault happens in the first call to the
function and some printfs where enough to arrive to what seems the
key.
The C subroutine receives an array in its second argument:
int __next_partition_of_size_p(SV* k_avptr, SV* M_avptr, int p) {
AV* k = GETAV(k_avptr);
AV* M = GETAV(M_avptr);
...
}
that is initialized in the Perl side:
my @M = (0) x $q;
push @M, $_ - $q + 1 for $q..(@$data-1);
...
__next_partition_of_size_p([EMAIL PROTECTED], [EMAIL PROTECTED], $p)
The values of $q and @$data do not matter, they are correct. OK,
[EMAIL PROTECTED] is passed to the function as the second argument, and if I
print its contents in XS I get garbage from some index on. Just in
case, that call lives in a closure:
my $iter = Algorithm::Combinatorics::Iterator->new(sub {
__next_partition_of_size_p([EMAIL PROTECTED], [EMAIL PROTECTED], $p) ==
-1 ? ...;
}, __slice_partition_of_size_p([EMAIL PROTECTED], $p, $data));
NOW THE MISTERY COMES, If I just print @M in Perl before that line,
the values in XS are right and execution completes without errors.
I mean, I just really added
print join(", ", @M), "\n";
before the call and all of a sudden the values of M in the XS side
are fine and thus the code completes OK.
I am puzzled here! Any ideas?
That was the key in fact.
Problem was in 5.6.x there's no guarantee simple arithmetic with
integers gives an SV with a IV slot:
$ ~/local/perl-5.6.2/bin/perl -MDevel::Peek -e '$a = 1; $b = $a +
1; Dump $b'
SV = NV(0x180a810) at 0x1807730
REFCNT = 1
FLAGS = (NOK,pNOK)
NV = 2
Since the macro I used to pick integers was SvIVX my code was broken
in that version. Switching to SvIV is all I need to fix the module
for 5.6.x.
This changed in 5.8:
Perl now tries internally to use integer values in numeric
conversions
and basic arithmetics (+ − * /) if the arguments are integers, and
tries also to keep the results stored internally as integers. This
change leads to often slightly faster and always less lossy arith‐
metics. (Previously Perl always preferred floating point numbers
in its
math.)
But now that I reread that delta I see it just says "tries", so from
a formal point of view my use of SvIVX was incorrect even in 5.8.x,
albeit it worked in practice.
Marvin, thank you very much for your help.
-- fxn