1

libmba を含む XS モジュールをコンパイルする C での初心者レベルの経験では、この警告を解決できません。

helmut@Helmuts-MacBook-Air:~/github/LCS-XS$ make
"/Users/helmut/perl5/perlbrew/perls/perl-5.18.2/bin/perl"    "/Users/helmut/perl5/perlbrew/perls/perl-5.18.2/lib/5.18.2/ExtUtils/xsubpp"  -typemap "/Users/helmut/perl5/perlbrew/perls/perl-  5.18.2/lib/5.18.2/ExtUtils/typemap"  XS.xs > XS.xsc && mv XS.xsc XS.c
cc -c  -I. -fno-common -DPERL_DARWIN -fno-strict-aliasing -pipe - fstack-protector -I/usr/local/include -I/opt/local/include -O3   - DVERSION=\"0.01\" -DXS_VERSION=\"0.01\"  "- I/Users/helmut/perl5/perlbrew/perls/perl-5.18.2/lib/5.18.2/darwin- 2level/CORE"   XS.c
  XS.xs:55:26: warning: passing 'const void *' to parameter of type 'AV  *' (aka 'struct av *') discards qualifiers
    [-Wincompatible-pointer-types-discards-qualifiers]
       SV *line = *av_fetch(a, idx, 0);
                            ^
/Users/helmut/perl5/perlbrew/perls/perl-5.18.2/lib/5.18.2/darwin- 2level/CORE/embed.h:51:46: note: expanded from macro
'av_fetch'
#define av_fetch(a,b,c)         Perl_av_fetch(aTHX_ a,b,c)
                                                    ^
/Users/helmut/perl5/perlbrew/perls/perl-5.18.2/lib/5.18.2/darwin- 2level/CORE/proto.h:178:44: note: passing argument to
  parameter 'av' here
    PERL_CALLCONV SV**      Perl_av_fetch(pTHX_ AV *av, I32 key, I32 lval)
                                                   ^
1 warning generated.

コンパイルされたモジュールは正常に動作しています。しかし、警告なしにコーディングする方法はありますか?

LCS/XS.xs の関連部分:

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"

#include <string.h>

#include <mba/diff.h>
#include <mba/diff.c>

/* snipped */

inline
static const void * 
_av_idx(const void *a, int idx, void *context)
{
   //AV *av = a;
   SV *line = *av_fetch(a, idx, 0);
   STRLEN klen;
   char *key = SvPVbyte(line, klen);
   //printf("key: %s\n",key);

  return key;
}

/* snipped */

void lcs_LCS(obj, s1, s2)
  SV *obj
  AV * s1
  AV * s2

  PREINIT:
    struct CTX *ctx = (struct CTX *)SvIVX(SvRV(obj));

  PPCODE:
    int d, sn, i;
    struct varray *ses = varray_new(sizeof(struct diff_edit), NULL);

    IV n;
    IV m;
    n = av_top_index(s1);
    m = av_top_index(s2);

    // call libmba::diff()
    d = diff(s1, 0, n, s2, 0, m, &_av_idx, &_cmp_str,  NULL, 0, ses, &sn, NULL);

mba/diff.h の部分

typedef const void *(*idx_fn)(const void *s, int idx, void *context);

そして、mba/diff.c で:

int
diff(const void *a, int aoff, int n,
    const void *b, int boff, int m,
    idx_fn idx, cmp_fn cmp, void *context, int dmax,
    struct varray *ses, int *sn,
    struct varray *buf)
{

libmba のソースを変更せずにこの警告を解決する良い方法はありますか?

解決済み:

inline
static const void * 
_av_idx(const void *a, int idx, void *context)
{
    SV *line = *av_fetch((AV *)a, idx, 0);
    //                   ^^^^^^
    STRLEN klen;
    char *key = SvPVbyte(line, klen);

    return key;
}
4

1 に答える 1

0

さて..._av_idxあなたは最初のパラメータの内容を変更しないことを約束しています

inline static const void *_av_idx(const void *a, int idx, void *context)
//                                ^^^^^

av_fetch(a, idx, 0)しかし、その後、そのパラメーターを変更しないことを約束しない関数 ( ) に送信します。それはあなたの約束を少し奇妙にします。

約束を外して…

inline static const void *_av_idx(void *a, int idx, void *context)
//                       no const ^^^^^^^

編集

または、引数をローカル変数にコピーして渡すこともできます

inline
static const void * 
_av_idx(const void *a, int idx, void *context)
{
   AV *a_copy;
   deep_copy(a_copy, a);
   if (a_copy != NULL) {
       SV *line = *av_fetch(a_copy, idx, 0);
       free(a_copy);
   } else {
       /* error */
   }
   STRLEN klen;
   char *key = SvPVbyte(line, klen);
   //printf("key: %s\n",key);

  return key;
}
于 2015-06-20T09:37:52.850 に答える