1

bonsoir smile
voilà j'ai compilé ce programme:

#include <stdio.h>
#include <conio.h>

void main(void)
{ 
 int i;
         char *str0 = "Hello";
	char str1[]="Hello";

	printf ("str0=%s str1=%s\n",str0,str1);
	
	printf ("\n&str0=%d str0=%d Hello=%d str0->=%c\n",&str0,str0,"Hello",*str0);
	printf ("\n&str1=%d str1=%d Hello=%d str1->=%c\n",&str1,str1,"Hello",*str1);
	
	getch();
    /*  *scr0='a';       erreur à l'execution */
	*str1='a';
	
	printf ("\n&str0=%d str0=%d Hello=%d str0->=%c\n",&str0,str0,"Hello",*str0);
	printf ("\n&str1=%d str1=%d Hello=%d str1->=%c\n",&str1,str1,"Hello",*str1);
    
	getch();

}


sous visual C++ en reprenant l'exemple de la doc de TIGCC qui explique la différence entre ces deux déclarations : char *str = "Hello"; et char str[] = "Hello";
mais ya des trucs que je comprend pas

1/ L'erreur à l'execution mais ça doit être à cause VC++ donc c pas grave ....

2/ Le résultat du prog
str0 = Hello      str1=Hello

&str0=1245048    str0=4325520    Hello=4325520    str0->=H

&str1=1245040    str1=1245040    Hello=4325520    str1->=H

&str0=1245048    str0=4325520    Hello=4325520    str0->=H

&str1=1245040    str1=1245040    Hello=4325520    str1->=a


j'espère que je me trompe mais j'ai comme l'impression que ça signifie que str1 pointe sur lui même tout en pointant sur le tableau qui contient la chaîne "Hello" parce que je peux la modifier ... enfin bref je comprend rien grin

si quelqu'un peu m'expliquer le problème merci smile
avatar
Qu'il est beau ce chien !!! :)

2

Attends confirmation, y'a des chances pour que je me plante, mais à mon avis :

La chaine "Hello" est présente plusieurs fois dans ton programme en tant que constante, donc TIGCC "optimise" et ne la crée qu'une seule fois : "Hello" et l'adresse pointée par str0 sont identiques. Par contre avec char str1[], là tu déclare un tableau qui contient la chaine "Hello" (qui ne prend donc pas 4 octets comme un pointeur, mais 6 : strlen("Hello")+1). Tu peux modifier str1 sans problème.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

3

Tu n'as pas le droit de modifier une chaîne littérale. char *str0 = "Hello"; pointe directement vers la chaîne littérale, donc interdit de le modifier. char str1[]="Hello"; te donne une copie modifiable.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

4

donc TIGCC "optimise" et ne la crée qu'une seule fois

ouais , pour l'instant c'est ss VC++ que je l'ai compilé mais il fait peut être comme TIGCC ... même si ça m'étonnerais

Kevin> ok, donc il y a une erreur ds la doc de TIGCC(chapitre "ponctuators\quotes"):
for (i = 0; i < 2; i++)
  {
    char str[] = "Hello";
    printf (str);
    str[0] = 'a';
  }

This program will work as expected (it will display "Hello" twice). But, if you change 'str[]' to '*str',
 it will not work as expected (it will display "Hello" and then "aello"). 

car en changeant str[] en *str on obtient une erreur et pas un "aello" ...

e str1[] me donne une copie modifiable ne m'explique tjs pas (enfin vu mon niveau c ptet normal :-D) pourquoi le contenu de str1 et sa propre adresse son identiques (et surtout différents de l'adresse de la chaîne "Hello"). Je ne vois donc pas comment cette instruction *str1='a';le fait qu pourrait modifier la chaîne "Hello" alors que logiquement elle devrait modifier le contenu de la case pointée par str1, qui n'est autre que str1 confus . Au dernier printf j'aurais donc dû obtenir
&str1=ascii('a') str1=ascii('a')
ce truc me parait illogique (même s'il est fort probable que ce soit moi qui ait l'esprit tordu grin)
avatar
Qu'il est beau ce chien !!! :)

5

imbibinebe
:
donc TIGCC "optimise" et ne la crée qu'une seule fois
ouais , pour l'instant c'est ss VC++ que je l'ai compilé mais il fait peut être comme TIGCC ... même si ça m'étonnerais

Et bien tu vas être étonné : VC++ et GCC (et donc TIGCC) optimisent ça en ne créant qu'une seule chaîne.
Kevin> ok, donc il y a une erreur ds la doc de TIGCC(chapitre "ponctuators\quotes"):
for (i = 0; i < 2; i++)
  {
    char str[] = "Hello";
    printf (str);
    str[0] = 'a';
  }

This program will work as expected (it will display "Hello" twice). But, if you change 'str[]' to '*str',
 it will not work as expected (it will display "Hello" and then "aello"). 
car en changeant str[] en *str on obtient une erreur et pas un "aello" ...

C'est parce que ce qui se passe à ce moment-là est indéfini : sur PC, il y a des mécanismes de protections (gérés par une partie du processeur qui s'appelle la MMU) qui font que dès que tu essayes de modifier qqch que tu n'as pas le droit de modifier, tu as une erreur; sur TI, il n'y a pas de MMU et donc le contenu est effectivement modifié et il n'y a pas d'erreur : seulement, ça va te donner des choses bizarres si tu te fies à ce comportement, par exemple si tu utilises deux fois la chaîne "Hello", les deux chaînes seront modifiées simultanément. Bref, le comportement sur PC est préférable (il te permet de débugger plus facilement).
C'est vrai qu'il faudrait peut-être une remarque en plus insistant sur le fait que c'est interdit de mettre "*str".
le fait que str1[] me donne une copie modifiable ne m'explique tjs pas (enfin vu mon niveau c ptet normal :-D) pourquoi le contenu de str1 et sa propre adresse son identiques

&str1 te donne un pointeur vers un tableau de taille 6. Et un pointeur vers un tableau est ensuite automatiquement converti en un pointeur vers un élément du tableau; c'est effectivement un peu bizarre. Essaye juste d'éviter &str1 (pointeur vers un tableau) parce que tu vas avoir des comportements bizarres, notamment :
char *p=&str1;
return p[0]!=0;

(qui est équivalent à "str1[0] != '\0'", i.e. teste si str1 est non vide) n'a rien à voir avec :
return (&str1)[0]!=0;
(qui est équivalent à "*&str1 != 0" i.e. "str1 != 0" i.e. "str1 != NULL", qui est toujours vrai).

On peut d'ailleurs très bien faire sans pointeurs de tableaux, personnellement je n'en ai utilisé pratiquement jamais (et il y a toujours moyen de contourner).

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

6

car en changeant str[] en *str on obtient une erreur et pas un "aello" ...

pas normal qu'on ait une erreur, ma foi...
(enfin, j'ai pas testé, mais d'après ce que dit le C, il me semble que ça devrait marcher)
avatar
Tutorial C (TI-89/92+/v200) - Articles Développement Web (PHP, Javascript, ...)
« What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against? » - Larry Wall

7

squale92> c'est une segfault au runtime et pas une erreur de compilation, je pense

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

8

squale92> c'est une segfault au runtime et pas une erreur de compilation, je pense

argh, j'avais pas fait gaffe au fait que c'était sur PC et non sur TI sad
bon, alors, l'erreur est plus compréhensible... mais effectivement, m'étonnerai que ce soit à la compilation smile
avatar
Tutorial C (TI-89/92+/v200) - Articles Développement Web (PHP, Javascript, ...)
« What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against? » - Larry Wall

9

pollux> ça m'énerve les trucs bizarres comme ça grin
merci pour tes explications smile
squale>en effet je parlais d'erreur à l'execution sur PC, j'ai pas encore testé avec TIGCC ...
avatar
Qu'il est beau ce chien !!! :)

10

squale>en effet je parlais d'erreur à l'execution sur PC, j'ai pas encore testé avec TIGCC ...

OK smile
(d'ailleurs, en relisant le post 0, je vois que tu l'avais dit... pas fait gaffe, et vu qu'on est sur le forum TI, j'ai supposé que ct pour TI)
avatar
Tutorial C (TI-89/92+/v200) - Articles Développement Web (PHP, Javascript, ...)
« What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against? » - Larry Wall

11

C'est surtout que ca devrait etre interdit dans la norme d'ecrire des horreurs comme :
char *str="Hello";
La syntaxe correcte est:
const char *str="Hello";

12

imbibinebe
: car en changeant str[] en *str on obtient une erreur et pas un "aello" ...

Sur la TI-89/92+/V200, il n'y a pas de protection mémoire (MMU), donc la calculatrice ne peut pas t'empêcher de faire cette bêtise.
PpHd :
C'est surtout que ca devrait etre interdit dans la norme d'ecrire des horreurs comme :
char *str="Hello";
La syntaxe correcte est: const char *str="Hello";

C'est pour ça qu'il y a -Wwrite-strings. smile Qui est mis par défaut par l'IDE, d'ailleurs. smile
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

13

PpHd> 1] on est pas en C++ (en particulier, le fait qu'il n'y ait pas de mutable rend les const plus ou moins inutilisables en pratique s'il n'y a pas de hack gore, et en fait je ne sais même pas si les hacks gores sont légaux ou pas), 2] certains compilo traditionnels supposaient que les string étaient modifiables... je pense qu'il n'ont pas voulu casser ces progs et qu'ils ont juste rajouté un switch compilo

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

14

1. Ca n'a rien a voir avec du C++, c'est du C89. (Qu'est-ce que cette histoire de mutable et de hack gore ?).
2. Ca aurait du donner un warning en C89 et une erreur en C99 !!!!!!

15

Ralàlà Pollux t'y connais rien smile
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

16

1. Je ne dis pas que 'const' n'est pas un mot-clé du C90 roll C'est juste que sans mutable, on ne peut pas utiliser systématiquement des const, parce que le fait de ne rien toucher du tout dans une structure passée en tant que const est souvent très contraignant (imagine un compteur de référence, ou un compteur d'utilisations pour le debug ou d'autres choses qui ne changent pas fondamentalement la sémantique de la structure, tout en changeant une partie de la représentation binaire). Résultat, en général je n'utilise jamais des const en C. Ca ne paraît donc pas déraisonnable de ne pas utiliser des 'const char *' pour les chaînes non plus si on ne s'en sert pas ailleurs... (c'est juste une convention différente, même si celle avec les "const" permet d'éviter des erreurs de débutant et n'est donc pas une si mauvaise idée que ça)
2. Le fait de modifier une chaîne, oui ça devrait être une erreur (mais on ne peut le détecter qu'au runtime). Le fait de ne pas s'être amusé à rajouter des 'const' un peu partout, non. Mais ça peut être une bonne idée d'en faire un warning par défaut, quitte à le désactiver si on ne l'aime pas (c'est ce que fait TIGCC).

Thibaut> smile

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

17

1. Desole mais moi je mets des const partout. Et on peut utiliser systematiquement des const. Jure! Il suffit de bien programmer en C, ce qui ne semble pas etre ton cas tongue

18

Pollux :
1. Je ne dis pas que 'const' n'est pas un mot-clé du C90 roll C'est juste que sans mutable, on ne peut pas utiliser systématiquement des const, parce que le fait de ne rien toucher du tout dans une structure passée en tant que const est souvent très contraignant (imagine un compteur de référence, ou un compteur d'utilisations pour le debug ou d'autres choses qui ne changent pas fondamentalement la sémantique de la structure, tout en changeant une partie de la représentation binaire). Résultat, en général je n'utilise jamais des const en C. Ca ne paraît donc pas déraisonnable de ne pas utiliser des 'const char *' pour les chaînes non plus si on ne s'en sert pas ailleurs... (c'est juste une convention différente, même si celle avec les "const" permet d'éviter des erreurs de débutant et n'est donc pas une si mauvaise idée que ça)

Ton mutable est un hack extrèmement moche, parce que du coup les "constantes" n'en sont plus!
2. Le fait de modifier une chaîne, oui ça devrait être une erreur (mais on ne peut le détecter qu'au runtime). Le fait de ne pas s'être amusé à rajouter des 'const' un peu partout, non. Mais ça peut être une bonne idée d'en faire un warning par défaut, quitte à le désactiver si on ne l'aime pas (c'est ce que fait TIGCC).

Justement, le système des const est là pour pouvoir repérer ce genre d'erreurs en temps de compilation. (Et sans MMU, c'est soit les repérer en temps de compilation, soit ne pas les repérer du tout!)
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

19

PpHd :
1. Desole mais moi je mets des const partout. Et on peut utiliser systematiquement des const. Jure! Il suffit de bien programmer en C, ce qui ne semble pas etre ton cas tongue

Exemple?
typedef struct {
  SYM *symbol;
  char name[];
} IDENT;

long GetSize(const IDENT *i) {
  if (!i->symbol) {
    i->symbol=...;  // erreur !
  }
  return i->symbol.size;
}

Je ne dis pas que c'est très courant (surtout en C), mais lorsque tu tombes sur un cas comme ça, tu es obligé de supprimer le const et de propager cette suppression partout dans le prog... (et ce n'est pas non plus rarissime)
Ton mutable est un hack extrèmement moche, parce que du coup les "constantes" n'en sont plus!

Ce n'est pas "mon" mutable, c'est le mutable du C++. Non, l'intérêt, c'est qu'au lieu que const représente le fait que la structure binaire est constante, il représente le fait que la sémantique de l'objet est constante (c'est le cas dans l'exemple que j'ai donné : mettre à jour la définition d'un symbole n'est pas un changement sémantique, c'est juste un calcul fait de façon paresseuse).

Et au niveau du compilo, ça ne pose pas de problème : il sait juste que ce champ-là de l'objet peut être modifié. Sans le mutable, on serait obligé de déclarer toute la structure non-const (perte d'efficacité), et pas que dans la fonction feuille qui l'utilise, aussi dans toutes les fonctions appelantes.

Cela dit, il faut aussi préciser que le besoin de mutable se fait bien plus ressentir en C++ qu'en C : en particulier, si on veut faire du reference-counting, on est à peu près obligé d'avoir un mutable, ou alors de faire le truc gore décrit plus haut (supprimer tous les const).
Justement, le système des const est là pour pouvoir repérer ce genre d'erreurs en temps de compilation. (Et sans MMU, c'est soit les repérer en temps de compilation, soit ne pas les repérer du tout!)

On est bien d'accord que ce n'est pas inutile. Mais, le fait est que :
1) c'est pas assez flexible, justement (pas de mutable)
2) et on s'en passe très bien (je n'utilise pratiquement jamais 'const' en C, et je n'ai jamais eu de bug lié à ça); mais c'est plus propre de le faire qd même (d'où l'intérêt des mutable du C++)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

20

Je sais pas mais perso j'aurais plutot ecrit:
long GetSize(const IDENT *i) {
  return (i->symbol == NULL) ? 0: i->symbol.size;

ou
long GetSize(const IDENT *i) {
  assert(i->symbol != NULL)
  return i->symbol.size;

ou
long GetSize(const IDENT *i) {
  if (i->symbol == NULL)
     TRACE("i->symbol null");
  return i->symbol.size;


suivant ce que je veux faire.

21

Pollux
:
PpHd :
1. Desole mais moi je mets des const partout. Et on peut utiliser systematiquement des const. Jure! Il suffit de bien programmer en C, ce qui ne semble pas etre ton cas tongue

Exemple?
typedef struct {
  SYM *symbol;
  char name[];
} IDENT;

long GetSize(const IDENT *i) {
  if (!i->symbol) {
    i->symbol=...;  // erreur !
  }
  return i->symbol.size;
}
Je ne dis pas que c'est très courant (surtout en C), mais lorsque tu tombes sur un cas comme ça, tu es obligé de supprimer le const et de propager cette suppression partout dans le prog... (et ce n'est pas non plus rarissime)

((IDENT *)i)->symbol=...; // const_cast<IDENT *> en C++
Pas besoin de supprimer le const partout dans le programme.
Cela dit, c'est une grosse saleté de déclarer un paramètre const alors qu'il ne l'est pas, que ce soit avec mutable ou avec un truc de ce style.
Ton mutable est un hack extrèmement moche, parce que du coup les "constantes" n'en sont plus!
Ce n'est pas "mon" mutable, c'est le mutable du C++.

Je sais. Mais c'est toi qui proposes de l'utiliser.
Non, l'intérêt, c'est qu'au lieu que const représente le fait que la structure binaire est constante, il représente le fait que la sémantique de l'objet est constante (c'est le cas dans l'exemple que j'ai donné : mettre à jour la définition d'un symbole n'est pas un changement sémantique, c'est juste un calcul fait de façon paresseuse).

L'objet change, donc il n'est pas constant. Peu importe pourquoi il change.
Et au niveau du compilo, ça ne pose pas de problème : il sait juste que ce champ-là de l'objet peut être modifié.

Tu le déclares volatile et tu peux en faire ce que tu veux sans que l'optimisateur puisse en faire quelque chose.
Cela dit, il faut aussi préciser que le besoin de mutable se fait bien plus ressentir en C++ qu'en C : en particulier, si on veut faire du reference-counting, on est à peu près obligé d'avoir un mutable, ou alors de faire le truc gore décrit plus haut (supprimer tous les const).

Tu alloues ton reference count ailleurs et tu utilises un int *. Comme ça, tu peux changer le reference count sans modifier l'objet.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

22

PpHd>
Tu n'as pas compris (OK, j'aurais pu être plus explicite). Le but n'est pas de déclencher une erreur de compilation (de toute façon là ça n'aurait pas marché), le but est justement de définir (et donc de modifier) i->symbol à partir de i->name en cherchant dans une table.

Version plus explicite :
typedef struct {
SYM *symbol;
char name[];
} IDENT;

long GetSize(/*const*/ IDENT *i) {
if (!i->symbol)
i->symbol = DoIdentSearch(i->name);
return i->symbol.size; }


Mais ça ne marche pas si on laisse le const.

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

23

Dans ce cas il fallait pas le declarer const des le depart si tu autorises ce systeme.

Tu alloues ton reference count ailleurs et tu utilises un int *. Comme ça, tu peux changer le reference count sans modifier l'objet.

Ca a d'ailleurs un autre avantage dans giacs :0

24

Kevin Kofler
:
Pollux
:
PpHd :
1. Desole mais moi je mets des const partout. Et on peut utiliser systematiquement des const. Jure! Il suffit de bien programmer en C, ce qui ne semble pas etre ton cas tongue

Exemple?
typedef struct {
  SYM *symbol;
  char name[];
} IDENT;

long GetSize(const IDENT *i) {
  if (!i->symbol) {
    i->symbol=...;  // erreur !
  }
  return i->symbol.size;
}
Je ne dis pas que c'est très courant (surtout en C), mais lorsque tu tombes sur un cas comme ça, tu es obligé de supprimer le const et de propager cette suppression partout dans le prog... (et ce n'est pas non plus rarissime)

((IDENT *)i)->symbol=...; // const_cast<IDENT *> en C++
Pas besoin de supprimer le const partout dans le programme.

Si. Le compilo peut très bien faire des optimisations sales avec le const, par exemple faire une copie temporaire et utiliser la copie temporaire à la place du nouveau (voire encore plus sale, i.e. copier la moitié de l'adresse tout en laissant l'autre moitié intacte [et donc crash] ).
C'est bien ça le problème...
Cela dit, c'est une grosse saleté de déclarer un paramètre const alors qu'il ne l'est pas, que ce soit avec mutable ou avec un truc de ce style.

Je parle du point de vue sémantique. Et on écrit explicitement quelles sont les variables qui n'influent pas sur la sémantique (mais uniquement, par exemple, sur la rapidité), alors qu'avec ton cast gore on ne le sait même pas (et c'est donc encore plus trompeur).
Non, l'intérêt, c'est qu'au lieu que const représente le fait que la structure binaire est constante, il représente le fait que la sémantique de l'objet est constante (c'est le cas dans l'exemple que j'ai donné : mettre à jour la définition d'un symbole n'est pas un changement sémantique, c'est juste un calcul fait de façon paresseuse).
L'objet change, donc il n'est pas constant. Peu importe pourquoi il change.

Et? Ce n'est pas parce que dans une modélisation on considère que n'importe quel changement est significatif que c'est le cas dans toutes les modélisations. Et mon exemple montre clairement les limites de cette modélisation, donc si, "il importe".
Et au niveau du compilo, ça ne pose pas de problème : il sait juste que ce champ-là de l'objet peut être modifié.

Tu le déclares volatile et tu peux en faire ce que tu veux sans que l'optimisateur puisse en faire quelque chose.

Il faut donc mettre volatile à chaque accès de la variable même s'il n'a rien à voir avec le code qui modifie ça? couic

En plus, niveau performance, c'est encore pire : une boucle qui est dans une fonction feuille (voire même "localement feuille") ne peut pas stocker temporairement l'objet, et donc ça fait bobo au CSE :
for (size_t i=0;i<n;i++) {
  IDENT *id=t[[b][/b]i];
  DoStuffWith(id->symbol->type,id->symbol->size,id->symbol->value,id->symbol->loc);
}

Là tu obliges à redéréférencer 4 fois couic
Cela dit, il faut aussi préciser que le besoin de mutable se fait bien plus ressentir en C++ qu'en C : en particulier, si on veut faire du reference-counting, on est à peu près obligé d'avoir un mutable, ou alors de faire le truc gore décrit plus haut (supprimer tous les const).

Tu alloues ton reference count ailleurs et tu utilises un int *. Comme ça, tu peux changer le reference count sans modifier l'objet.

Oui, je me doute bien. Sauf que ça rajoute une indirection; et c'est franchement dommage pour un langage qui se veut bas niveau comme le C : la vérification supplémentaire du const se traduit par des contraires sur le code généré qui ne seraient pas là s'il y avait un mutable. Bref, complètement inadapté.

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

25

PpHd
: Dans ce cas il fallait pas le declarer const des le depart si tu autorises ce systeme.

gol
Si tu commences par faire ton programme en déclarant les trucs const, puis qu'après tu optimises tout ça pour éviter les lookups inutiles, et ben tu te fais baiser. Ce truc là m'est déjà arrivé, sauf que c'était en C++ => mutable happy

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

26

Pollux :
Si tu commences par faire ton programme en déclarant les trucs const, puis qu'après tu optimises tout ça pour éviter les lookups inutiles, et ben tu te fais baiser. Ce truc là m'est déjà arrivé, sauf que c'était en C++ => mutable happy

Que repondre ?
1. Tu sais pas programmer.
2. Et dans ce cas la: perl -pi -e 's/const IDENT */IDENT */g' **/*.{c,h}
3. Et Tu peux toujours faire une fonction/macro qui le verifie:
#define GetSize(x) (((x)->symbol == NULL ? (x)->symbol = deref((x)->name) : 0), GetSize(x))

Mais ca revient a colmater les breches d'une mauvaise conception.
(Oui je sais que je fais de la multi-evaluation. En GNU C, une petite var temporaire serait la bienvenue).

27

PpHd
:
Pollux :
Si tu commences par faire ton programme en déclarant les trucs const, puis qu'après tu optimises tout ça pour éviter les lookups inutiles, et ben tu te fais baiser. Ce truc là m'est déjà arrivé, sauf que c'était en C++ => mutable happy

Que repondre ? 1. Tu sais pas programmer.

Tout ce que ça veut dire, c'est que quand on écrit le mot 'const', il faut être absolument sûr qu'aucune fonction membre n'aura l'idée saugrenue d'aller mettre en cache un résultat, ou que si elle le fait, elle le fait dans une variable séparée triso (donc coût supplémentaire lié à la recherche de la bonne position dans cette variable, etc...) Pour moi, c'est clairement une faute de conception du mot-clé 'const', parce que quand on va écrire cette nouvelle fonction membre, on va devoir modifier toute l'interface, comme tu le dis :
2. Et dans ce cas la: perl -pi -e 's/const IDENT */IDENT */g' **/*.{c,h}

(j'ajouterais qu'en C++, un tel remplacement ne serait pas aussi simple, puisqu'il y a aussi les const des fonctions membres à traiter).

Et en plus si on fait comme tu le dis on perd tout l'intérêt du mot-clé const : il y a des cas où il n'y a pas de 'const' et où la donnée n'est jamais modifiée... Bref, si "pas de const" ne veut pas dire "attention, valeur modifiée", pour moi, il n'y a aucun intérêt à l'utiliser. Alors après, tu peux quand même vouloir utiliser const dans certains cas, mais admet au moins que ma position se tient.
3. Et Tu peux toujours faire une fonction/macro qui le verifie:
#define GetSize(x) (((x)->symbol == NULL ? (x)->symbol = deref((x)->name) : 0), GetSize(x))

Alors là, carrément pas. Ca supposerait aussi que la fonction appelante n'ait pas de const non plus, donc ça ne résoud rien du tout.
Mais ca revient a colmater les breches d'une mauvaise conception.

... du langage C, tu veux dire roll

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

28

De ton programme.

29

C'était ironique, cf le #roll#. Et tu ne réponds pas au reste.

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

30

1. Un objet pouvant utiliser un systeme de cache ne peut pas etre declare de const.
2. Tu ajustes au cas pas cas. Normalement une simple edition du .h .c suffit.
3. Dans ce cas tu refais l'implantation de ton module. Ce n'est absolument pas dur si tu as code correctement en C.

M'enfin, si ca marche pas c'est ta faute et pas celle du C. Le const marche tres bien.