What is the difference between sv_catpv () and sv_catpvs ()?

According to perlapi , sv_catpv() works as follows:

Concatenate the NUL line at the end of the line that is in SV. If the SV has a set of UTF-8 states, then the bytes enclosed must be valid UTF-8. Pens β€œreceive” magic, but do not β€œset” magic.

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

Most of the XS tutorials I found use sv_catpvs() , but this does the following:

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

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

Well, this is not very useful, so take a look at sv_catpvn() :

Concatenate a line to the end of a line that is in SV len indicates the number of bytes to copy. If the SV has a set of UTF-8 states, then the bytes enclosed must be valid UTF-8. Pens β€œreceive” magic, but do 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 accepts the string length as a separate parameter, and sv_catpvs matches sv_catpvn , except that it accepts a literal string.

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

+5
source share
1 answer

According to the passages you quoted, sv_catpvs only accepts 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 sv_catpvs all? Because it's faster. The reason sv_catpvs accepts only accepts a string literal - it is a macro that extends

 sv_catpvs(sv, "foo") 

into something like that

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

which permits

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

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

+6
source

Source: https://habr.com/ru/post/1205800/


All Articles