简体   繁体   English

如何避免 SvPV() 与 utf8n_to_uvchr() 的警告 [-Wpointer-sign] - XS 错误?

[英]How to avoid warning [-Wpointer-sign] of SvPV() versus utf8n_to_uvchr() - bug of XS?

This is the relevant part of XS, which should convert an Perl string from UTF-8 to codepoints (unsigned 32-bit integers):这是 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;
}

It throws this warning:它抛出这个警告:

~/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  \
          \

It works and passes my tests.它有效并通过了我的测试。 But if I want to deliver it to CPAN the distribution should not throw warnings.但是,如果我想将其交付给 CPAN,则分发不应发出警告。

Decode it with own code in C would be a work-around (and faster).在 C 中用自己的代码解码它是一种解决方法(而且速度更快)。

For me it looks like a bug in the XS macros and/or the example in the documentation are wrong.对我来说,它看起来像是 XS 宏中的错误和/或文档中的示例是错误的。

The interplay of U8 and char in the API is a bit weird. API 中 U8 和 char 的相互作用有点奇怪。 You might ask #p5p to see why it works that way.您可能会问 #p5p 以了解为什么它会这样工作。

Failing that, though, would some plain typecasting suppress the warnings?但是,如果做不到这一点,一些简单的类型转换会抑制警告吗? Is this in a public repository somewhere?这是在某个地方的公共存储库中吗?

Aside: SvPV is evil.旁白:SvPV 是邪恶的。 Its prevalence in XS modules causes quite a lot of pain.它在 XS 模块中的流行导致了相当多的痛苦。 Avoid it when possible.尽可能避免它。 See: https://dev.to/fgasper/perl-s-svpv-menace-5515请参阅: https://dev.to/fgasper/perl-s-svpv-menace-5515

Update: This looks to be a case where it's necessary to break the abstraction.更新:这看起来是一个需要打破抽象的案例。 Alas.唉。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM