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 :

[const] #define vs const


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par fearyourself
    Occupera aussi de la place mémoire....
    Non, tant qu'on n'utilise pas la macro.

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Mokhtar BEN MESSAOUD
    Dans le cas d'utilisaton de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define CHAINE "bonjour"
    je me demande si a chaque fois que le compilateur va retrouver la chaine "bonjour" dans le code ( resultat de preprocesseur) il y aura une allocation statique de 8 caracteres ( sizeof("bonjour") )?
    Ca dépend de l'implémentation et des reglages. Certains compilateurs créent une zone mémoire à chaque fois, d'autres une seule (option 'merge strings', par exemple), d'autres font des optimisations savantes du genre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char *sa = "bonjour";
    char *sb = "jour"
    avec 'sb' qui vaut 'sa + 3'... Beaucoup de choses sont possibles. En embarqué, on est friand de ce genre d'optimisations...

  3. #3
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Mokhtar BEN MESSAOUD
    je pense que le plus sur pour les constantes chaines de caracters d'utiliser
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char buffer[] = "bonjour"
    Ca dépend de l'usage. En embarqué, je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    static const char buffer[] = "bonjour";
    , c'est ce qui prend le moins de place (mémoire statique initialisée).

  4. #4
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par gege2061
    Premier cas :
    La chaîne "bonjour" est stockée dans le fichier exécutable (ce sont ces chaînes que l'on voit lorsque l'on ouvre un exécutable en tant que fichier texte).
    Pas tant que la macro n'est pas utilisée. Si elle l'est, la substitution s'opère, et une (ou plusieurs) chaine statique non modifiable est créée.
    Ensuite lors de son utilisation, par exemple :
    Le préprocesseur remplacera ceci par :
    Qui renvoi l'adresse de la chaîne [1] à la fonction puts.
    Ok.

    Deuxième cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    const char chaine [] = "bonjour"
    On commence par créer une zone mémoire de 8 bytes dans laquelle est recopiée la chaîne "bonjour" (cf premier cas pour ceux qui n'ont pas suivie).
    Dans ce cas, il n'est pas nécessaire de déclarer le contenu de la variable chaine constant,
    Ca dépend des cas. Si on veut réellement une chaine constante, mais sans le pointeur inutile, cette forme (avec 'static' permet de faire des économies de mémoire sustanciels, puisque qu'il suffit de disposer d'une seule zone initialisée. Pas de recopie à faire.

    Si la variable est locale, et/ou non const, il y a bien sûr recopie obligatoire. (Perte de temps et de mémoire).

  5. #5
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Mokhtar BEN MESSAOUD
    mais de point de vue de la taille de l'executable

    est-ce que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     puts("bonjour");
    puts("bonjour");
    puts("bonjour");
    prend plus ou moins d'espace que

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    const char* chaine = "bonjour";
    puts(chaine);
    puts(chaine);
    puts(chaine);
    Le deuxième est est certainement plus optimisé. Mais si le premier cas est optimisé, il est lègèrement plus performant, car on fait l'économie du pointeur. Si il est statique, ça peut compter...

  6. #6
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par fearyourself
    Citation Envoyé par gege2061
    Citation Envoyé par fearyourself
    Exactement la même taille
    Ah bon dans le second cas, on déclare une variable de taille sizeof (char *) après si le compilateur s'amuse à faire des optimisations, forcement on ne va pas s'en sortir
    Je ne suis pas convaincu... La taille de l'exécutable restera inchanger... Du moins c'est ce que dit mon petit doigt...

    C'est la fin de la journée, je vais y réflechir...
    C'est tout réfléchi, il y a un pointeur en plus.

    Hum, quoiqu'il pourrait être transformé en expression constante si
    - on ne le modifie pas
    - on ne prend jamais son adresse.

    Dans ce cas, les deux cas pourraient occuper la même place mémoire. Tout celà dépend fortement de l'implémentation.

  7. #7
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par DaZumba
    Mais je me demande bien pourquoi le posteur original se pose ce genre de questions. C'est pour faire une demo en moins de 64k?
    En embarqué, la question peut se poser... Notamment si le code est truffé de debugs avec __FILE__ ...

    J'ai déjà eu des gags...

  8. #8
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par Mokhtar BEN MESSAOUD
    Non c'est pour un systeme embarqué qui tourne sous linux
    Bienvenu au club !

  9. #9
    Membre confirmé
    Inscrit en
    Janvier 2005
    Messages
    100
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 100
    Par défaut
    Bon ca y est j'ai fait le test

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    #include <stdio.h>    
    #define CHAINE "bonjour"
    #define SOUSCHAINE "onjour"
     
     
    int main()
    {
     
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
     
    	printf(" address of %s = %p\n", SOUSCHAINE, &SOUSCHAINE);
    	printf(" address of %s = %p\n", SOUSCHAINE, &SOUSCHAINE);
    	printf(" address of %s = %p\n", SOUSCHAINE, &SOUSCHAINE);
    	printf(" address of %s = %p\n", SOUSCHAINE, &SOUSCHAINE);
    	printf(" address of %s = %p\n", SOUSCHAINE, &SOUSCHAINE);
     
    	 printf(" address of %s = %p\n", CHAINE, &CHAINE);
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
    	printf(" address of %s = %p\n", CHAINE, &CHAINE);
     
       printf(" address of %s = %p\n", SOUSCHAINE, &SOUSCHAINE);
    	printf(" address of %s = %p\n", SOUSCHAINE, &SOUSCHAINE);
    	printf(" address of %s = %p\n", SOUSCHAINE, &SOUSCHAINE);
    	printf(" address of %s = %p\n", SOUSCHAINE, &SOUSCHAINE);
    	printf(" address of %s = %p\n", SOUSCHAINE, &SOUSCHAINE);
     
     
    }
    le resultat est
    address of bonjour = 0x80486a8
    address of bonjour = 0x80486a8
    address of bonjour = 0x80486a8
    address of bonjour = 0x80486a8
    address of bonjour = 0x80486a8
    address of bonjour = 0x80486a8
    address of onjour = 0x80486c5
    address of onjour = 0x80486c5
    address of onjour = 0x80486c5
    address of onjour = 0x80486c5
    address of onjour = 0x80486c5
    address of bonjour = 0x80486a8
    address of bonjour = 0x80486a8
    address of bonjour = 0x80486a8
    address of bonjour = 0x80486a8
    address of bonjour = 0x80486a8
    address of bonjour = 0x80486a8
    address of onjour = 0x80486c5
    address of onjour = 0x80486c5
    address of onjour = 0x80486c5
    address of onjour = 0x80486c5
    address of onjour = 0x80486c5

    donc le compilateur optimise si les chaine sont identiques mais il n'optimise les sous chaines

  10. #10
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Si je reprends ton code, voici ce que j'obtiens:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    #include <stdio.h>
     
    #define TXT "Bonjour"
    #define TXT1 "onjour"
     
    int main()
    {
          printf("%p %s\n",TXT, TXT);
          printf("%p %s\n",TXT1, TXT1);
            return 1;
    }
    En effet en compilant comme ceci:
    J'obtiens:
    0x8048518 Bonjour
    0x8048527 onjour
    On voit bien qu'il ne gère pas les sous-chaîne... Mais si je compile comme ceci:
    J'obtiens:
    0x8048508 Bonjour
    0x8048509 onjour
    Il a géré correctement les sous-chaînes... Mais bien-sûr, il ne peut pas gérer toutes les sous-chaînes vu qu'il faut que la chaîne termine par '\0'

    Donc lorsqu'on fait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define TXT "Bonjour"
    #define TXT1 "onjou"
    On obtient (avec l'option -O3):
    0x8048508 Bonjour
    0x8048517 onjou
    Tout ceci pour dire que ce n'est pas aussi simple, que cela dépend de beaucoup de choses et bien sûr pas tous les compilateurs le feront, cela dépendera des options utilisées...

    Jc

  11. #11
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par fearyourself
    J'obtiens:
    0x8048508 Bonjour
    0x8048509 onjour
    Très intéressant. Je sais maintenant pourquoi je vais passer en -O3 ...
    Merci pour ce test.

    Tu a vu que ça n'optimisait pas en -O2 ?

  12. #12
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    Tu as vu que ça n'optimisait pas en -O2 ?
    J'ai tellement l'habitude de compiler en O3 (à cause des temps de performances des benchmarks) que je ne tente que très rarement les options O1, O2... Lorsque t'as posé ta question, je me suis dit: c'est quand même un truc basique, pourquoi il faudrait un O3... Et en effet, dès O1 c'est bon...

    Jc

  13. #13
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par fearyourself
    Tu as vu que ça n'optimisait pas en -O2 ?
    J'ai tellement l'habitude de compiler en O3 (à cause des temps de performances des benchmarks) que je ne tente que très rarement les options O1, O2... Lorsque t'as posé ta question, je me suis dit: c'est quand même un truc basique, pourquoi il faudrait un O3... Et en effet, dès O1 c'est bon...

    Jc
    OK, je laisse donc en -O2 jusqu'à nouvel ordre.

  14. #14
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    L'option O3 mets au moins en place généralement (et sur ma machine utilisant gcc 4.0 mais je pense que c'est pareil sur le 3.3):

    - inlining: qui n'est quand même pas négligeable
    - prefetch: sur les machines actuelles, cela peut considérablement réduire le temps d'exécution...

    De toute façon, si j'ai bien compris, tu travailles sur des systèmes embarqués. Généralement, la taille du code est plus petit en O3, le fait que le compilateur impémente le "inlining" fait que le nombre d'appel de fonctions est amoindri...

    Cela devrait être un point positif pour toi,
    Jc

  15. #15
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par fearyourself
    L'option O3 mets au moins en place généralement (et sur ma machine utilisant gcc 4.0 mais je pense que c'est pareil sur le 3.3):

    - inlining: qui n'est quand même pas négligeable
    - prefetch: sur les machines actuelles, cela peut considérablement réduire le temps d'exécution...

    De toute façon, si j'ai bien compris, tu travailles sur des systèmes embarqués. Généralement, la taille du code est plus petit en O3, le fait que le compilateur impémente le "inlining" fait que le nombre d'appel de fonctions est amoindri...

    Cela devrait être un point positif pour toi,
    Exact, j'ai gagné 20 % de code.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 2 PremièrePremière 12

Discussions similaires

  1. POO, constantes différence Define et Const
    Par SuperArbre dans le forum Langage
    Réponses: 4
    Dernier message: 14/05/2012, 15h05
  2. deux variables const et pas const
    Par contremaitre dans le forum C
    Réponses: 4
    Dernier message: 15/04/2008, 16h27
  3. Réponses: 13
    Dernier message: 02/04/2007, 11h04
  4. const char et const unsigned char
    Par moon93 dans le forum C
    Réponses: 8
    Dernier message: 04/08/2006, 15h59
  5. Différences entre #define et const
    Par Tittom dans le forum C
    Réponses: 19
    Dernier message: 01/06/2006, 13h48

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