2015-06-20 5 views
1

Компиляция XS-модуль с libmba я не могу решить это предупреждение с моим начинающих уровень опыта в C:Решить предупреждение: прохождение «константный недействительным *» для параметра типа «AV *»

[email protected]:~/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. 

Составленный модуль работает нормально. Но есть ли способ закодировать его без предупреждения?

Соответствующие части в ЛВП/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); 

Часть ЗБМ/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; 
} 
+0

'av_fetch ((AV *) a, idx, 0); 'следует удалить предупреждение. – wimh

+0

@Wimmel: Thx, это работает. Я помню, что пробовал это раньше, но не в финальной комбинации. –

+0

«Ложитесь в компилятор, и он отомстит». - Генри Спенсер (http://www.lysator.liu.se/c/henry/) – pmg

ответ

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; 
} 
+0

Затем я получаю 'несовместимые типы указателей 'для вызова' diff() '. –

+0

Также попытался удалить 'const' в typedef libmba/diff.h, но затем он несколько раз предупреждает о компиляции libmba/diff.c. –

+0

Вы также можете скопировать аргумент в локальную переменную и передать это 'av_fetch()'; см. мое редактирование – pmg