[英]How to avoid warning [-Wpointer-sign] of SvPV() versus utf8n_to_uvchr() - bug of XS?
这是 XS 的相关部分,它应该将 Perl 字符串从 UTF-8 转换为代码点(无符号 32 位整数):
UV *
text2UV (SV *sv, STRLEN *lenp)
{
STRLEN len;
// char *str = SvPV(foo_sv, strlen);
// char *s = SvPV (sv, len); // This original version warns
U8 *s = (U8 *)SvPV (sv, len); // This casts without warning
UV *r = (UV *)SvPVX (sv_2mortal (NEWSV (0, (len + 1) * sizeof (UV))));
UV *p = r;
if (SvUTF8 (sv))
{
STRLEN clen;
while (len)
{
// UV utf8_to_uvchr_buf(const U8 *s, const U8 *send, STRLEN *retlen)
*p++ = utf8n_to_uvchr (s, len, &clen, 0);
if (clen < 0)
croak ("illegal unicode character in string");
s += clen;
len -= clen;
}
}
else
while (len--)
*p++ = *(unsigned char *)s++;
*lenp = p - r;
return r;
}
它抛出这个警告:
~/github/perl/Text-Levenshtein-BVXS$ make
cp BVXS.pm blib/lib/Text/Levenshtein/BVXS.pm
Running Mkbootstrap for BVXS ()
chmod 644 "BVXS.bs"
"/Users/helmut/perl5/perlbrew/perls/perl-5.32.0/bin/perl" -MExtUtils::Command::MM -e 'cp_nonempty' -- BVXS.bs blib/arch/auto/Text/Levenshtein/BVXS/BVXS.bs 644
"/Users/helmut/perl5/perlbrew/perls/perl-5.32.0/bin/perl" "/Users/helmut/perl5/perlbrew/perls/perl-5.32.0/lib/5.32.0/ExtUtils/xsubpp" -typemap '/Users/helmut/perl5/perlbrew/perls/perl-5.32.0/lib/5.32.0/ExtUtils/typemap' BVXS.xs > BVXS.xsc
mv BVXS.xsc BVXS.c
cc -c -I. -fno-common -DPERL_DARWIN -mmacosx-version-min=10.14 -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -I/opt/local/include -DPERL_USE_SAFE_PUTENV -O3 -DVERSION=\"0.01\" -DXS_VERSION=\"0.01\" "-I/Users/helmut/perl5/perlbrew/perls/perl-5.32.0/lib/5.32.0/darwin-2level/CORE" BVXS.c
BVXS.xs:26:35: warning: passing 'char *' to parameter of type 'const U8 *' (aka 'const unsigned char *') converts between pointers to integer types with different sign [-Wpointer-sign]
*p++ = utf8n_to_uvchr (s, len, &clen, 0);
^
/Users/helmut/perl5/perlbrew/perls/perl-5.32.0/lib/5.32.0/darwin-2level/CORE/utf8.h:74:54: note: expanded from macro 'utf8n_to_uvchr'
utf8n_to_uvchr_error(s, len, lenp, flags, 0)
^
/Users/helmut/perl5/perlbrew/perls/perl-5.32.0/lib/5.32.0/darwin-2level/CORE/utf8.h:76:45: note: expanded from macro 'utf8n_to_uvchr_error'
utf8n_to_uvchr_msgs(s, len, lenp, flags, errors, 0)
^
/Users/helmut/perl5/perlbrew/perls/perl-5.32.0/lib/5.32.0/darwin-2level/CORE/inline.h:1781:36: note: passing argument to parameter 's' here
Perl_utf8n_to_uvchr_msgs(const U8 *s,
^
1 warning generated.
rm -f blib/arch/auto/Text/Levenshtein/BVXS/BVXS.bundle
cc -mmacosx-version-min=10.14 -bundle -undefined dynamic_lookup -L/usr/local/lib -L/opt/local/lib -fstack-protector-strong BVXS.o -o blib/arch/auto/Text/Levenshtein/BVXS/BVXS.bundle \
\
它有效并通过了我的测试。 但是,如果我想将其交付给 CPAN,则分发不应发出警告。
在 C 中用自己的代码解码它是一种解决方法(而且速度更快)。
对我来说,它看起来像是 XS 宏中的错误和/或文档中的示例是错误的。
API 中 U8 和 char 的相互作用有点奇怪。 您可能会问 #p5p 以了解为什么它会这样工作。
但是,如果做不到这一点,一些简单的类型转换会抑制警告吗? 这是在某个地方的公共存储库中吗?
旁白:SvPV 是邪恶的。 它在 XS 模块中的流行导致了相当多的痛苦。 尽可能避免它。 请参阅: https://dev.to/fgasper/perl-s-svpv-menace-5515
更新:这看起来是一个需要打破抽象的案例。 唉。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.