Non, tant qu'on n'utilise pas la macro.Envoyé par fearyourself
Non, tant qu'on n'utilise pas la macro.Envoyé par fearyourself
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 genreEnvoyé par Mokhtar BEN MESSAOUD
avec 'sb' qui vaut 'sa + 3'... Beaucoup de choses sont possibles. En embarqué, on est friand de ce genre d'optimisations...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 char *sa = "bonjour"; char *sb = "jour"
Ca dépend de l'usage. En embarqué, je fais :Envoyé par Mokhtar BEN MESSAOUD
, c'est ce qui prend le moins de place (mémoire statique initialisée).
Code : Sélectionner tout - Visualiser dans une fenêtre à part static const char buffer[] = "bonjour";
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.Envoyé par gege2061
Ok.Ensuite lors de son utilisation, par exemple :
Le préprocesseur remplacera ceci par :
Code : Sélectionner tout - Visualiser dans une fenêtre à part puts (TXT);
Qui renvoi l'adresse de la chaîne [1] à la fonction puts.
Code : Sélectionner tout - Visualiser dans une fenêtre à part puts ("bonjour");
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.
Deuxième cas :
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).
Code : Sélectionner tout - Visualiser dans une fenêtre à part const char chaine [] = "bonjour"
Dans ce cas, il n'est pas nécessaire de déclarer le contenu de la variable chaine constant,
Si la variable est locale, et/ou non const, il y a bien sûr recopie obligatoire. (Perte de temps et de mémoire).
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...Envoyé par Mokhtar BEN MESSAOUD
C'est tout réfléchi, il y a un pointeur en plus.Envoyé par fearyourself
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.
En embarqué, la question peut se poser... Notamment si le code est truffé de debugs avec __FILE__ ...Envoyé par DaZumba
J'ai déjà eu des gags...
Bienvenu au club !Envoyé par Mokhtar BEN MESSAOUD
Bon ca y est j'ai fait le test
le resultat est
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); }donc le compilateur optimise si les chaine sont identiques mais il n'optimise les sous chainesaddress 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
Si je reprends ton code, voici ce que j'obtiens:
En effet en compilant comme ceci:
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; }
J'obtiens:
Code : Sélectionner tout - Visualiser dans une fenêtre à part gcc texte.c
On voit bien qu'il ne gère pas les sous-chaîne... Mais si je compile comme ceci:0x8048518 Bonjour
0x8048527 onjour
J'obtiens:
Code : Sélectionner tout - Visualiser dans une fenêtre à part gcc texte.c -O3
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'0x8048508 Bonjour
0x8048509 onjour
Donc lorsqu'on fait:On obtient (avec l'option -O3):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 #define TXT "Bonjour" #define TXT1 "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...0x8048508 Bonjour
0x8048517 onjou
Jc
Très intéressant. Je sais maintenant pourquoi je vais passer en -O3 ...Envoyé par fearyourself
Merci pour ce test.
Tu a vu que ça n'optimisait pas en -O2 ?
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.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,
Jc
Exact, j'ai gagné 20 % de code.Envoyé par fearyourself
Partager