• [^] # Re: Problème de programmation C

    Posté par . En réponse au message warning: cast from pointer to integer of different size. Évalué à 2.

    Pour vc1decbit.c: il s'agit d'une macro utilisée pour tracer des messages de debug (DEBUG2) qui est en cause, ou plutôt son utilisation. Note qu'en mode non-debug, cette macro est définie par une expression nulle, le warning n'apparaît donc qu'en mode DEBUG (plus précisément, quand la macro NDEBUG est definie).
    Exemple, ligne 473:
    DEBUG2(vc1DEBUG_BIT, "Initialise Bitstream Start=0x%08x Length=%d\n",
    (int)pBuffer, Length);

    Sans aller voir la fonction qui est utilisée, on sent qu'elle doit être basée sur uen fonction de la famille de printf() (à vérifier). Si c'est le cas, alors ils utilisent le format %x pour afficher en hexadécimal les valeurs du pointeur pBuffer. Vu qu'il ne s'agit que d'un message de debug, on peut je pense changer la ligne (qui, de toute façon, invoque au mieux un comportement implementation-defined) en:
    DEBUG2(vc1DEBUG_BIT, "Initialise Bitstream Start=%p Length=%d\n",
    (void *)pBuffer, Length);

    Ainsi, on ne risque pas de warning, et c'est portable. L'affichage sera juste un peu différent, mais si c'est juste pour le debug, changer le format d'affichage ne devrait pas gêner outre mesure.
    Note que le cast en void * est nécessaire.

    Ce n'est pas un problème spécifique à un passage de 32 à 64 bits, mais juste une utilisation de propriétés implementation-defined (voire undefined) de gestion des pointeurs qui a été mis en évidence par un changement d'architecture...

    Pour vc1decblk.c: le problème vient de:
    vc1recon.h:
    void vc1RECON_ReconstructMB (const HWD16 pTCoefs[6][64], const UBYTE8
    pPredBlk[6][64], vc1_sReferencePicture *pRefPic, vc1_sPosition *pPosition, vc1_eProfile eProfile)

    vc1decblk.c:
    vc1_eResult vc1DECBLK_DecodeBlockLayer(
    vc1DEC_sState * pState,
    vc1DEC_sBitstream * pBitstream)
    {
    HWD16 TCoefs[6][64] = {{0}};
    UBYTE8 PredBlk[6][64];
    /* ... */
    vc1RECON_ReconstructMB(TCoefs,
    PredBlk,
    pState->pCurrentRef,
    pPosition,
    pState->sSeqParams.eProfile);

    Ainsi, les 2 premiers paramètres passés à vc1RECON_ReconstructMB sont définis comme des tableaux, mais le passage en paramètre d'un tableau le convertit implicitement en pointeur. Comme il s'agit de tableaux multi-dimensionels, 6.5.2.1 dit que TCoefs est converti en un pointeur vers HWD16 [64], alors que la fonction attend un pointeur vers const HWD16 [64]. Pour vc1recon.c: les lignes 110 et 120 ont le même problême que pour vc1decblk.c: un assignation de pointeurs de type diférents, la différence étant due au qualificateur const.

    Apres une petite recherche sur comp.lang.c, j'ai trouvé dans la FAQ ceci: http://c-faq.com/ansi/constmismatch.html
    Pour résumer, le moyen de contourner le problème est de faire un cast. Pas propre, tout ça...
    Ou alors il faudrait enlever le const du prototype des fonctions en cause. Cette dernière solution aurait au moins le mérite de ne plus causer de problème; mais je supose que les const sont là pour optimiser un chouia le code. On peut les virer au moins pour commencer (il vaut mieux faire du code qui marche et ensuite l'optimiser, que créer un code optimisé et ensuite le corriger).

    Note que la ligne 120 de vc1recon.c pose un autre problème: un paramètre formel de la fonction, de type tableau multidimensionel (donc, en réalité, pointeur sur tableau), est réassigné ! C'est légal du point de vue du C (pour autant que je sache), mais c'est très moche...