Various SvPV() macros return pointers to constant empty strings

I was wondering if anyone understood the use cases in sv_2pv_flags()
where it returns a pointer to a constant empty string. (There are
several cases, two of which IMO are somewhat understandable, but one
of which I don't get at all.)

So for instance i have code like this:

SV *tmp= sv_newmortal();
char *pv;
sv_grow(tmp,1000);
pv= SvPV_nolen();

this throws an uninitialized warning because the POK flag is off, but
it then returns the pointer 51c97a every time. Looking into the source
code it falls into a code path that does:

3255: return (char *)"";

I think this is bloody weird. If I dump the sv it has a valid PV
pointer (because of the sv_grow()), but it has not actually coerced it
to a string, and it has not returned the actual pointer to the PV
slot. I feel like this code should have "just worked" and returning a
constant string here when there is a valid SvPVX to return is wrong.

Yves



-- 
perl -Mre=debug -e "/just|another|perl|hacker/"
0
demerphq
9/6/2019 11:05:50 AM
perl.perl5.porters 47776 articles. 1 followers. Follow

2 Replies
3 Views

Similar Articles

[PageSpeed] 22

On Fri, 6 Sep 2019 at 13:05, demerphq <demerphq@gmail.com> wrote:
>
> I was wondering if anyone understood the use cases in sv_2pv_flags()
> where it returns a pointer to a constant empty string. (There are
> several cases, two of which IMO are somewhat understandable, but one
> of which I don't get at all.)
>
> So for instance i have code like this:
>
> SV *tmp= sv_newmortal();
> char *pv;
> sv_grow(tmp,1000);
> pv= SvPV_nolen();
>
> this throws an uninitialized warning because the POK flag is off, but
> it then returns the pointer 51c97a every time. Looking into the source
> code it falls into a code path that does:
>
> 3255: return (char *)"";
>
> I think this is bloody weird. If I dump the sv it has a valid PV
> pointer (because of the sv_grow()), but it has not actually coerced it
> to a string, and it has not returned the actual pointer to the PV
> slot. I feel like this code should have "just worked" and returning a
> constant string here when there is a valid SvPVX to return is wrong.

FWIW, i feel like a function like:

STRLEN len= 1000;
char *foo= SvPV_force_minlen(sv,len)

would be nice, which would return a pointer to the pv buffer owned by
'sv', with a minimum length of 1000 bytes, and set the SvCUR() to
1000, and set the POK flag to on. (And/or maybe allow a flag argument
that would silence warnings.)

Maybe this is just too use cases specific, but I find myself often
doing patterns like this when I want to construct an error or
something like that.

cheers,
Yves



-- 
perl -Mre=debug -e "/just|another|perl|hacker/"
0
demerphq
9/6/2019 11:18:03 AM
On Fri, Sep 06, 2019 at 01:05:50PM +0200, demerphq wrote:
> I was wondering if anyone understood the use cases in sv_2pv_flags()
> where it returns a pointer to a constant empty string. (There are
> several cases, two of which IMO are somewhat understandable, but one
> of which I don't get at all.)
> 
> So for instance i have code like this:
> 
> SV *tmp= sv_newmortal();
> char *pv;
> sv_grow(tmp,1000);
> pv= SvPV_nolen();
> 
> this throws an uninitialized warning because the POK flag is off, but
> it then returns the pointer 51c97a every time. Looking into the source
> code it falls into a code path that does:
> 
> 3255: return (char *)"";
> 
> I think this is bloody weird. If I dump the sv it has a valid PV
> pointer (because of the sv_grow()), but it has not actually coerced it
> to a string, and it has not returned the actual pointer to the PV
> slot. I feel like this code should have "just worked" and returning a
> constant string here when there is a valid SvPVX to return is wrong.

The current behaviour seems sane to me.

Neither of the PV flags are set, so whatever the PV pointer points at
is irrelevant.

The only way I could see it being vaguely reasonable to return the PV
pointer would be if SvPV() NUL terminated the buffer iff there was a
PV buffer and neither PV flag was set, but why do that?

If you want the PV pointer to manipulate the buffer you can use
SvPVX() (or save the result of SvGROW()/sv_grow()).

Tony
0
tony
9/7/2019 3:09:37 AM
Reply: