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

Embarqué Discussion :

Constante avec un cast


Sujet :

Embarqué

  1. #1
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    74
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 74
    Points : 44
    Points
    44
    Par défaut Constante avec un cast
    Bonjour à tous et à toutes
    j'aimerai bien savoir la signification de la ligne suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define DSPI_A    (*( volatile struct DSPI_tag *)      0xFFF90000)
    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 483
    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 483
    Points : 13 681
    Points
    13 681
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Prenons par étapes :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define DSPI_A    (UNE_VALEUR)
    --> le passage du préprocesseur permet de remplacer DSPI_A par UNE_VALEUR
    Il est bon de parenthéser la définition de UNE_VALEUR comme fait ici, pour s'assurer que ça va rester un seul morceau lors de l'évaluation et non se mixer avec autre chose. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define QUATRE 2+2
    int a = 2*QUATRE
    // a devient 2*2+2 = 10 et non 8


    L'adresse 0xFFF90000 est caster pour être interpréter comme un pointeur sur TYPE puis on déréférence ce pointeur pour récupérer la valeur.



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    volatile struct DSPI_tag
    TYPE est une structure DSPI_tag. Le qualificatif volatile est une indication pour le compilateur : http://c.developpez.com/faq/?page=va...#VARS_volatile


    Au final :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define DSPI_A    (*( volatile struct DSPI_tag *)      0xFFF90000)
    te permet d'avoir une constante DPSI_A qui vaut la valeur de la structure DSPI_tag qui est à l'adresse 0xFFF90000.

  3. #3
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Si j'avais eu une explication aussi claire la première fois que j'ai fait de l'embarqué, j'aurais été heureux. Tiens Bktero, attrape ça .

  4. #4
    Membre émérite
    Inscrit en
    Avril 2010
    Messages
    1 495
    Détails du profil
    Informations forums :
    Inscription : Avril 2010
    Messages : 1 495
    Points : 2 274
    Points
    2 274
    Par défaut
    Salut,

    Citation Envoyé par Bktero Voir le message
    Il est bon de parenthéser la définition de UNE_VALEUR
    Pour une UNE_VALEUR, pas forcément, mais pour UNE_EXPRESSION, certainement.

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 483
    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 483
    Points : 13 681
    Points
    13 681
    Billets dans le blog
    1
    Par défaut
    Si j'avais eu une explication aussi claire la première fois que j'ai fait de l'embarqué, j'aurais été heureux. Tiens Bktero, attrape ça
    Merci

    Pour une UNE_VALEUR, pas forcément, mais pour UNE_EXPRESSION, certainement.
    Si on voulait être extrémiste, on pourrait dire que UNE_EXPRESSION s'évaluera en UNE_VALEUR ^^

    UNE_EXPRESSION serait peut-être plus adapté dans le cas général en effet.

    Précisons d'ailleurs que si ce qui est intéressant dans la macro est l'ensemble des effets de bord de UNE_EXPRESSION et non UNE_VALEUR qui sera évaluée, on peut mettre des accolades :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define EXIT_WITH_MESSAGE(msg) {puts(msg); exit(1);}

  6. #6
    Membre expérimenté

    Homme Profil pro
    Collégien
    Inscrit en
    Juillet 2010
    Messages
    559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Afghanistan

    Informations professionnelles :
    Activité : Collégien

    Informations forums :
    Inscription : Juillet 2010
    Messages : 559
    Points : 1 432
    Points
    1 432
    Par défaut
    Bonjour,

    Les MACRO ne sont pas remplaçables, mais je pense qu'elles sont trop dangereuses pour pouvoir en en abuser ( A consommer avec modération).

    Le c99 introduit le mot clef inline qui permet de faire de la vérification de type à la compilation.

    Je préfère (quand cela est possible) systématiquement remplacer les macro par des méthodes inline.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    static inline struct DSPI_tag getDSPI_tag()
    {
      return *(( volatile struct DSPI_tag *)0xFFF90000);
    }
    static inline struct DSPI_tag * getpDSPI_tag()
    {
      return ( struct truct DSPI_tag *)0xFFF90000);
    }
    Après le c99 n'est toujours disponible.

  7. #7
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define EXIT_WITH_MESSAGE(msg) {puts(msg); exit(1);}
    Il est d'usage d'utiliser un do while(0) lorsque l'on écrit une macro composée de plusieurs lignes (statments) ; cela afin de rester le plus largement compatible avec les différents types de C (K&R, 90 ...).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #define EXIT_WITH_MESSAGE(msg) do { \
       puts(msg); \
       exit(1); \
    } while(0)
    Citation Envoyé par mith06 Voir le message
    Les MACRO ne sont pas remplaçables, mais je pense qu'elles sont trop dangereuses pour pouvoir en en abuser ( A consommer avec modération).
    [...]
    Après le c99 n'est toujours disponible.
    Exactement ; lorsque l'on est cantonné à du C K&R (alias ANSI) ou 90 et que l'on propose une API, on a souvent l'obligation d'utiliser des macros. Un grand classique (notamment en embarqué j'imagine) est de définir des macros permettant à la compilation la vérification de la taille des types employés, de faire des endian swaps, etc.

    Lorsque ces macros sont bien écrites et bien documentées, je ne vois pas vraiment le danger.

  8. #8
    Membre éclairé Avatar de crocodilex
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    697
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 697
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par prgasp77 Voir le message
    Il est d'usage d'utiliser un do while(0) lorsque l'on écrit une macro composée de plusieurs lignes (statments) ; cela afin de rester le plus largement compatible avec les différents types de C (K&R, 90 ...).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #define EXIT_WITH_MESSAGE(msg) do { \
       puts(msg); \
       exit(1); \
    } while(0)
    Je ne vois pas bien où est le rapport avec la compatibilité avec les différents types de C.
    Le do while(0) est utile lorsqu'on a ce type d'écriture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if ( [...] )
       EXIT_WITH_MESSAGE(msg);
    else
       AUTRE_CHOSE(xxx);

  9. #9
    Membre émérite
    Avatar de prgasp77
    Homme Profil pro
    Ingénieur en systèmes embarqués
    Inscrit en
    Juin 2004
    Messages
    1 306
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur en systèmes embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 306
    Points : 2 466
    Points
    2 466
    Par défaut
    Merci j'ai dit une bêtise. Le #define MACRO {expressions} est a éviter (préférer le do while(0)) pour la raison expliquée dans la doc du précompilateur de GCC : Swallowing the semicolon − The C preprocessor.

    Traduction approximative pour nos amis non anglophones :
    [L'encapsulation d'expressions entre accolades dans la définition d'une macro] peut poser problème lorsque cette amcro est appelée avant un else, et cela car le point-virgule (;) serait alors considéré comme une expression vide. Supposons le cas suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #define SKIP_SPACES(p, limit)  \
       { char *lim = (limit);  \
          while (p < lim) { \
             if (*p++ != ' ') { \
                p--; break; }}}
    
    if (*p != 0)
       SKIP_SPACES (p, lim);
    else ...
    La présence de deux expressions − la macro d'une part et l'expression nulle (le point-virgule) d'autre part entre le if et le else − en fait un code invalide.

    C'est effectivement ce que tu dis ... Ainsi mieux vaut protéger ses macro d'un do while(0) systématiquement.

  10. #10
    Membre du Club
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    74
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 74
    Points : 44
    Points
    44
    Par défaut
    Merci à tous et à toutes de vos réponse

Discussions similaires

  1. Probleme avec un CAST
    Par freud dans le forum SQL
    Réponses: 9
    Dernier message: 02/03/2009, 21h25
  2. Renvoyer un pointeur avec un cast ?
    Par tintin72 dans le forum C
    Réponses: 8
    Dernier message: 19/05/2008, 18h08
  3. Concaténation d'une constante avec une variable
    Par perlgirl dans le forum Langage
    Réponses: 3
    Dernier message: 24/08/2007, 14h07
  4. problème avec des cast
    Par deubelte dans le forum C++
    Réponses: 3
    Dernier message: 26/02/2007, 18h11
  5. Réponses: 7
    Dernier message: 06/05/2006, 15h24

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