7th Kevin has asked for the wisdom of the Perl Monks concerning the following question:
I had the following code in an XS module. It is attempting to cycle through all of the entries in the scratchpad associated with a sub, and for each entry having a valid name, where the name also is found in another hash, I want to do something.
for (i = 0; i <= av_len(padn); ++i) { HE *hent; SV **nameptr = av_fetch(padn, i, 0); if (nameptr != NULL && SvPOKp(*nameptr) && (hent = hv_fetch_ent(hvn, *nameptr, 0, 0)) != NULL) { /* do something interesting with the value from hent */ } }
This worked, most of the time. However, for two of the names I was interested in, *nameptr was valid but the hv_fetch_ent failed, even though the name was in the hash indicated by hvn (which is HV *).
I then changed it to something like this:
for (i = 0; i <= av_len(padn); ++i) { HE *hent; SV **nameptr = av_fetch(padn, i, 0); if (nameptr != NULL && SvPOKp(*nameptr)) { SV **field; U32 len; const char *name = SvPV(*nameptr, len); if ((field = hv_fetch(hvn, name, len, 0)) != NULL) { /* do something interesting with *field */ } } }
but that failed in the same way.
I did some research (i.e., lots of printfs) and discovered that in these two cases _only_, the length associated with *nameptr was too large. One of the values was six characters long, the other was 5 (names "@stack" and "@trim" respectively), but the lengths were 235 and 236, respectively. I found it interesting but not enlightening that the wrong values were both 241 minus the correct value.
The code I have now works, but I am less than happy with it:
for (i = 0; i <= av_len(padn); ++i) { SV **nameptr = av_fetch(padn, i, 0); if (nameptr != NULL && SvPOKp(*nameptr)) { SV **field; const char *name = SvPV_nolen(*nameptr); if ((field = hv_fetch(hvn, name, strlen(name), 0)) != NULL) { /* do something interesting with *field */ } } }
In other words, the length associated with the SV* is wrong, but using good ol' C "strlen" works. Huh?
I know this borders on (if it doesn't cross into) forbidden magic, so maybe I should just accept that there are things I wasn't Meant To Know, but I am interested to hear if anyone has any clues about this Why didn't the length match up? Why did only some of them not match up (I didn't mention it, but one of the things I did was print out the name and name lengths of everything where *nameptr was valid). Why did the same names work properly some places?
This is perl, v5.8.6 built for darwin-thread-multi-2level (with 3 registered patches, see perl -V for more detail)
Kevin, perplexed
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Invalid SV name length in pad?
by dave_the_m (Monsignor) on Jul 06, 2007 at 10:03 UTC | |
by 7th Kevin (Novice) on Jul 07, 2007 at 00:13 UTC | |
|
Re: Invalid SV name length in pad?
by diotalevi (Canon) on Jul 06, 2007 at 02:05 UTC |