Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between sv_catpv() and sv_catpvs()?

Tags:

perl

xs

According to perlapi, sv_catpv() works as follows:

Concatenates the NUL-terminated string onto the end of the string which is in the SV. If the SV has the UTF-8 status set, then the bytes appended should be valid UTF-8. Handles 'get' magic, but not 'set' magic.

void sv_catpv(SV *const sv, const char* ptr)

Most of the XS tutorials I've found use sv_catpvs(), though, which does this:

Like sv_catpvn, but takes a literal string instead of a string/length pair.

void sv_catpvs(SV* sv, const char* s)

Well, that's not very helpful, so let's look at sv_catpvn():

Concatenates the string onto the end of the string which is in the SV. The len indicates number of bytes to copy. If the SV has the UTF-8 status set, then the bytes appended should be valid UTF-8. Handles 'get' magic, but not 'set' magic.

void sv_catpvn(SV *dsv, const char *sstr, STRLEN len)

So, sv_catpvn does the same thing as sv_catpv except that it takes the string length as a separate parameter, and sv_catpvs is the same as sv_catpvn except it takes the literal string.

Is there some subtle difference between sv_catpv and sv_catpvs that I'm missing, or are they just two ways to do the same thing?

like image 363
DarkMorford Avatar asked Oct 29 '14 17:10

DarkMorford


1 Answers

As per the passages you quoted, sv_catpvs only takes a string literal.

const char *str = "foo";

sv_catpvs(sv, "foo");   // ok
sv_catpvs(sv, str);     // ERROR

sv_catpv, on the other hand, accepts any expression that returns a string.

sv_catpv(sv, "foo");    // ok
sv_catpv(sv, str);      // ok

So why does sv_catpvs exist at all? Because it's faster. The reason sv_catpvs takes only takes a string literal is that it's a macro that expands

sv_catpvs(sv, "foo")

into something similar to

sv_catpvn_flags(sv, "foo", sizeof("foo")-1, SV_GMAGIC)

which resolves to

sv_catpvn_flags(sv, "foo", 3, SV_GMAGIC)

at compile-time. sv_catpv, on the other hand, is forced to use slower strlen.

like image 192
ikegami Avatar answered Sep 16 '22 12:09

ikegami