IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Conversion sur un champ de structure avec taille spécifiée


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8
    Points : 8
    Points
    8
    Par défaut Conversion sur un champ de structure avec taille spécifiée
    Bonjour,

    Je travaille sur un projet (qui n'est pas de moi) et, par habitude, j'ai décidé d'ajouter "quelques" flags à la compilation.
    Je passe sur les milliers (non non je n'exagère pas !!) de warnings qui sortent pour parler d'un seul que je ne sais pas comment fixer.

    J'ai une structure donc un champ est défini comme unsigned aligned: 5 et, dans le code, j'ai l'instruction ad->aligned = n; où n est un "int".
    GCC me sort le warning suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    warning: conversion to ‘unsigned char:5’ from ‘int’ may alter its value
    Que puis-je faire (mis à part enlever -Wconversion pour ne plus voir cette chose ) ?

    Merci d'avance.

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    Il faudrait réussir à caster l'affectation (il arrêtera de crier mais tu risques toujours l'altération de la valeur, of corse)..... Mais j'arrive pas à trouver l'écriture qui va bien

  3. #3
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    Il faut juste vérifier que n ne soit pas négatif.
    Est-il possible que n soit négatif?
    S'il est négatif, que voudrais-tu avoir comme valeur?

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Il faudrait réussir à caster l'affectation (il arrêtera de crier mais tu risques toujours l'altération de la valeur, of corse)..... Mais j'arrive pas à trouver l'écriture qui va bien
    Je n'ai pas la moindre idée de comment caster ça :s
    Pour ce qui est de l'altération de la valeur, cast ou pas cast le risque sera le même.
    L'intérêt du cast serait juste de faire taire GCC...


    Citation Envoyé par Neckara Voir le message
    Est-il possible que n soit négatif?
    S'il est négatif, que voudrais-tu avoir comme valeur?
    Je ne suis pas chez moi donc je ne peux pas te l'affirmer mais de mémoire il me semble que n ne peut pas être négatif.

    Citation Envoyé par Neckara Voir le message
    Il faut juste vérifier que n ne soit pas négatif.
    Le fait de tester que n n'est pas négatif résout un éventuel problème d'altération de la valeur mais ne va malheureusement rien changer quant au warning, non ?

  5. #5
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    Un cast fera taire le warning.
    Si tu vérifie que n n'est pas négatif ou si tu sais que n ne sera jamais négatif, tu n'auras aucun problème d'altération de la valeur.

  6. #6
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    La seule façon de supprimer le warning sans enlever -Wconversion est d'appliquer un masque de 5 bits à la valeur que tu assignes (valeur qui doit être unsigned) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    unsigned foo = 12;
    s.aligned = foo & 0x1F;

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    Vérifier que n est négatif ou pas ne résout pas tout, à mon avis. Tu passes d'une valeur sur 32 bits (int) vers une valeur sur 5 bits. Avec un nombre négatif, vu que l'information est codée en complément à 2, les bits de poids fort seront forcément modifiés, mais tu peux avoir un nombre négatif dépensant le format. Il faut tester que le nombre est entre 0 et 2^5-1.

    Eviter l'altération possible de la valeur et résoudre l'affichage du warning sont deux choses séparées, enfin.... presque ^^ Tester la plage de valeur résout la possible altération ; le cast résout l'affichage.

    Sur la page de manuel de GCC à propos des options, on lit :
    The following '-W...' options are not implied by '-Wall'. Some of them warn about constructions that users generally do not consider questionable, but which occasionally you might wish to check for; others warn about constructions that are necessary or hard to avoid in some cases, and there is no simple way to modify the code to suppress the warning
    -WConversion fait partie de ces options là, tu fais peut-être partie du cas en gras.

    Pour résoudre au mieux le problème, il faudrait voir plus large. Que contient la structure à part ça ? En fonction de ça, tu peux faire un truc dans le genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    ypedef union
    {
        union
        {
            unsigned int aligned:5;
            unsigned int padding:27;
        } bitfields;
        unsigned int accesseur;
    } structure_t;
     
    int main(int argc, char *argv[])
    {
        argv=NULL;
        argc=0;
     
        structure_t test_s;
        unsigned int a = 5;
        test_s.accesseur = a & 0x1F ; // car 0x1F == 0b11111
        return test_s.bitfields.aligned;
    }
    EDIT : un tel code fait des assertions sur l'endianness des bits !

    D'après un warning de MinGW, unsigned char aligned:5; serait un type d'une extension de GCC et ne serait pas standard. Je l'ai donc remis en int pour cette raison.

  8. #8
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 012
    Points : 23 136
    Points
    23 136
    Par défaut
    N'est-ce pas plus lent de faire des calculs sur 5bits que sur un int ?

    Dans ce cas là, ne vaut-il mieux pas utiliser un unsigned int et utiliser des masques ?

    Mais que veux-tu faire dans le cas où la valeur serait négative ou seraient trop grande ?
    Vas-tu calculer une "valeur juste" à partir de ta valeur "fausse" ?
    Vas-tu retourner un message d'erreur ?
    Est-ce impossible ?

  9. #9
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Bktero c'est très dangereux ce que tu fais avec l'accesseur. En tout cas ce n'est pas portable. Dans la norme rien ne dit où sont placés les bits, et rien ne garantit que que les premiers bits seront les plus à droite. D'ailleurs sur ma plateforme les champs déclarés en premier sont mis dans les bits de poids fort.

    Dans mon message précédent j'ai donné la seule façon de supprimer le warning. Il n'y en a pas d'autre. En C il n'y a pas de cast vers les types "bit field".

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    En soi, je suis d'accord que mon code n'a pas grand intérêt. C'est pour ça que je dis qu'il faut voir le contexte plus globale de la structure en question. Et se poser des questions comme celles que tu poses

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Septembre 2011
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8
    Points : 8
    Points
    8
    Par défaut
    Comme je l'ai déjà évoqué dans mon premier message, je ne travaille pas sur mon code. De plus, je ne fais cela que par intérêt personnel.
    Par conséquent, même s'il est possible que cette implémentation ne soit pas la meilleure niveau performance ou tout autre problème, je n'ai pas l'intention de le modifier.

    Citation Envoyé par matafan Voir le message
    La seule façon de supprimer le warning sans enlever -Wconversion est d'appliquer un masque de 5 bits à la valeur que tu assignes
    Avec un test juste avant (comme évoqué dans beaucoup de réponses), cela semble parfait ! Je teste ce soir ;-)


    Merci à tous.

  12. #12
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 678
    Points
    13 678
    Billets dans le blog
    1
    Par défaut
    @Matafan : mince je n'avais vu aucun de tes 2 messages
    Je devais être en train de rédiger quand tu postais les tiens...

    Effectivement, mon code se base sur l'endianess des bits et ne garanti pas grand chose.

    appliquer un masque de 5 bits à la valeur que tu assignes --> mince je croyais avoir essayer sans succès Effectivement ça marche très bien. Je vais noter cette astuce

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 26/08/2011, 15h24
  2. erreur de segmentation sur affectation champ enum structure
    Par marion5515 dans le forum Débuter
    Réponses: 9
    Dernier message: 24/02/2010, 11h51
  3. Réponses: 8
    Dernier message: 13/11/2008, 21h28
  4. Réponses: 2
    Dernier message: 18/12/2006, 18h03
  5. Se positionner sur un champ ou DBNavigator avec recherche ..
    Par Djedjeridoo dans le forum Bases de données
    Réponses: 3
    Dernier message: 27/02/2006, 16h25

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo