Vincent Lefevre écrivit:Dans l'article <bh7r8s$ka3$,
Antoine Leca écrit:Le diagnostic serait le même (en fait, serait encore plus
justifié) si on avait (unsigned char*)p - (signed char*)q.
En l'occurence, du fait des contraintes spécifiques sur
les tableaux de caractères (en C99, 6.2.6, 6.2.5p15),
on sait que cela "doit" fonctionner. Mais ce n'est pas "légal".
Comment ça, "fonctionner"?
Si tu fais abstraction de la clause spécifique de 6.5.6
qui énonce la contrainte. On peut concevoir, pour le cas
particulier des pointeurs vers type caractère, une relaxe de
cette contrainte. Et alors, le reste « fonctionne ».
L'implémentation peut très bien émettre
un diagnostic et renvoyer 0 pour toute opération du style
(unsigned char*)p - (signed char*)q.
Oui oui. Je ne me place plus dans le cadre de la norme,
l'essayais d'imaginer ce qui se passe si on enlève la
contrainte.
Dans ce cas, tu ne "peux plus" renvoyer 0, il "faut" renvoyer la
valeur logique et naturelle, sur laquelle il n'y a pas ce me semble
d'ambiguité, même dans le cas des architectures tordues (il faut
bien voir que vu du comité, les cas explicites de comportement
indéfini sont en fait les cas où « cela ne passe pas » pour
certaines architectures).
Vincent Lefevre écrivit:
Dans l'article <bh7r8s$ka3$1@shakotay.alphanet.ch>,
Antoine Leca <root@localhost.gov> écrit:
Le diagnostic serait le même (en fait, serait encore plus
justifié) si on avait (unsigned char*)p - (signed char*)q.
En l'occurence, du fait des contraintes spécifiques sur
les tableaux de caractères (en C99, 6.2.6, 6.2.5p15),
on sait que cela "doit" fonctionner. Mais ce n'est pas "légal".
Comment ça, "fonctionner"?
Si tu fais abstraction de la clause spécifique de 6.5.6
qui énonce la contrainte. On peut concevoir, pour le cas
particulier des pointeurs vers type caractère, une relaxe de
cette contrainte. Et alors, le reste « fonctionne ».
L'implémentation peut très bien émettre
un diagnostic et renvoyer 0 pour toute opération du style
(unsigned char*)p - (signed char*)q.
Oui oui. Je ne me place plus dans le cadre de la norme,
l'essayais d'imaginer ce qui se passe si on enlève la
contrainte.
Dans ce cas, tu ne "peux plus" renvoyer 0, il "faut" renvoyer la
valeur logique et naturelle, sur laquelle il n'y a pas ce me semble
d'ambiguité, même dans le cas des architectures tordues (il faut
bien voir que vu du comité, les cas explicites de comportement
indéfini sont en fait les cas où « cela ne passe pas » pour
certaines architectures).
Vincent Lefevre écrivit:Dans l'article <bh7r8s$ka3$,
Antoine Leca écrit:Le diagnostic serait le même (en fait, serait encore plus
justifié) si on avait (unsigned char*)p - (signed char*)q.
En l'occurence, du fait des contraintes spécifiques sur
les tableaux de caractères (en C99, 6.2.6, 6.2.5p15),
on sait que cela "doit" fonctionner. Mais ce n'est pas "légal".
Comment ça, "fonctionner"?
Si tu fais abstraction de la clause spécifique de 6.5.6
qui énonce la contrainte. On peut concevoir, pour le cas
particulier des pointeurs vers type caractère, une relaxe de
cette contrainte. Et alors, le reste « fonctionne ».
L'implémentation peut très bien émettre
un diagnostic et renvoyer 0 pour toute opération du style
(unsigned char*)p - (signed char*)q.
Oui oui. Je ne me place plus dans le cadre de la norme,
l'essayais d'imaginer ce qui se passe si on enlève la
contrainte.
Dans ce cas, tu ne "peux plus" renvoyer 0, il "faut" renvoyer la
valeur logique et naturelle, sur laquelle il n'y a pas ce me semble
d'ambiguité, même dans le cas des architectures tordues (il faut
bien voir que vu du comité, les cas explicites de comportement
indéfini sont en fait les cas où « cela ne passe pas » pour
certaines architectures).
Mmmm. D'abord, pour les langages conçus aujourd'hui (et qui
ne cherchent pas la compatibilité avec C), char existe, mais il
est (potentiellement) plus grand qu'un byte; ce qui résoud le
problème.
Ce qui n'existe plus « si c'était à refaire », c'est l'affirmation
comme quoi l'unité de stockage élémentaire (le byte ou multiplet,
et en pratique l'octet) permette de stocker un caractère.
Mmmm. D'abord, pour les langages conçus aujourd'hui (et qui
ne cherchent pas la compatibilité avec C), char existe, mais il
est (potentiellement) plus grand qu'un byte; ce qui résoud le
problème.
Ce qui n'existe plus « si c'était à refaire », c'est l'affirmation
comme quoi l'unité de stockage élémentaire (le byte ou multiplet,
et en pratique l'octet) permette de stocker un caractère.
Mmmm. D'abord, pour les langages conçus aujourd'hui (et qui
ne cherchent pas la compatibilité avec C), char existe, mais il
est (potentiellement) plus grand qu'un byte; ce qui résoud le
problème.
Ce qui n'existe plus « si c'était à refaire », c'est l'affirmation
comme quoi l'unité de stockage élémentaire (le byte ou multiplet,
et en pratique l'octet) permette de stocker un caractère.
Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien
a savoir hormis les fonctions qui lui sont applicables (interface).
C'est exactement ce que je veux. C'est pour palier au probleme des
alias.
typedef void* object;
typedef object array;
typedef object list;
J'ai voulu avoir qqchose dont l'utilisateur ne peut rien faire sans
transtypage violent auquel cas il rompt le contrat.
Peut-être; cela étant, si C était un langage « sûr », cela se
saurait...
Cela a ces avantages et ces inconvenients. Avec un peu de methode et
de discipline de programmation, il peut le devenir suffisamment pour
de gros projet sans devenir un casse tete pour autant.
Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien
a savoir hormis les fonctions qui lui sont applicables (interface).
C'est exactement ce que je veux. C'est pour palier au probleme des
alias.
typedef void* object;
typedef object array;
typedef object list;
J'ai voulu avoir qqchose dont l'utilisateur ne peut rien faire sans
transtypage violent auquel cas il rompt le contrat.
Peut-être; cela étant, si C était un langage « sûr », cela se
saurait...
Cela a ces avantages et ces inconvenients. Avec un peu de methode et
de discipline de programmation, il peut le devenir suffisamment pour
de gros projet sans devenir un casse tete pour autant.
Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien
a savoir hormis les fonctions qui lui sont applicables (interface).
C'est exactement ce que je veux. C'est pour palier au probleme des
alias.
typedef void* object;
typedef object array;
typedef object list;
J'ai voulu avoir qqchose dont l'utilisateur ne peut rien faire sans
transtypage violent auquel cas il rompt le contrat.
Peut-être; cela étant, si C était un langage « sûr », cela se
saurait...
Cela a ces avantages et ces inconvenients. Avec un peu de methode et
de discipline de programmation, il peut le devenir suffisamment pour
de gros projet sans devenir un casse tete pour autant.
Laurent Deniau écrivit:Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien
a savoir hormis les fonctions qui lui sont applicables (interface).
Ah. Quelque chose comme
struct adt;
C'est exactement ce que je veux. C'est pour palier au probleme des
alias.
typedef void* object;
typedef object array;
typedef object list;
typedef struct elem array[];
typedef struct list_elem list;
Si tu y tiens,
typedef struct elem object;
Mais cela n'apporte rien, àmha.
Bien sûr. Cela étant, àmha il n'est pas nécessaire de rajouter
const dans ton type : cela invite au meutre, et j'ai du mal à
voir la valeur ajoutée.
Laurent Deniau écrivit:
Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien
a savoir hormis les fonctions qui lui sont applicables (interface).
Ah. Quelque chose comme
struct adt;
C'est exactement ce que je veux. C'est pour palier au probleme des
alias.
typedef void* object;
typedef object array;
typedef object list;
typedef struct elem array[];
typedef struct list_elem list;
Si tu y tiens,
typedef struct elem object;
Mais cela n'apporte rien, àmha.
Bien sûr. Cela étant, àmha il n'est pas nécessaire de rajouter
const dans ton type : cela invite au meutre, et j'ai du mal à
voir la valeur ajoutée.
Laurent Deniau écrivit:Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien
a savoir hormis les fonctions qui lui sont applicables (interface).
Ah. Quelque chose comme
struct adt;
C'est exactement ce que je veux. C'est pour palier au probleme des
alias.
typedef void* object;
typedef object array;
typedef object list;
typedef struct elem array[];
typedef struct list_elem list;
Si tu y tiens,
typedef struct elem object;
Mais cela n'apporte rien, àmha.
Bien sûr. Cela étant, àmha il n'est pas nécessaire de rajouter
const dans ton type : cela invite au meutre, et j'ai du mal à
voir la valeur ajoutée.
Laurent Deniau writes:
| Antoine Leca wrote:
| > Laurent Deniau écrivit:
| >
| >>Typiquement mon ADT en C ressemble a ca:
| > Heu, excusez la question du Neu-neu, ADT, que es aco?
|
| Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien a
| savoir hormis les fonctions qui lui sont applicables (interface).
|
| >>#define D_ADT struct { void const * const _; } *
| > Dangereux cela, tu définis un structure anonyme (différente)
| > à chaque invocation de la macro; c'est peut-être ce que tu
| > veux, mais d'autres pourrait facilement se méprendre...
|
| C'est exactement ce que je veux. C'est pour palier au probleme des alias.
------------------------------------------------------------------------
Comment ? À partir du moment où tu mets void* en début de ta
structure, tu dis au compilo que n'importe quel pointeur de données
peut aliaser ta structure. I.e. tu fais exactement el contraire de ce
que tu voudrais.
| typedef void* object;
| typedef object array;
| typedef object list;
|
| une list peut aller la ou un array est attendu, ce que je ne veux pas.
Mais ce que tu as proposé aupravant n'est pas une solution non plus !
Laurent Deniau <Laurent.Deniau@cern.ch> writes:
| Antoine Leca wrote:
| > Laurent Deniau écrivit:
| >
| >>Typiquement mon ADT en C ressemble a ca:
| > Heu, excusez la question du Neu-neu, ADT, que es aco?
|
| Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien a
| savoir hormis les fonctions qui lui sont applicables (interface).
|
| >>#define D_ADT struct { void const * const _; } *
| > Dangereux cela, tu définis un structure anonyme (différente)
| > à chaque invocation de la macro; c'est peut-être ce que tu
| > veux, mais d'autres pourrait facilement se méprendre...
|
| C'est exactement ce que je veux. C'est pour palier au probleme des alias.
------------------------------------------------------------------------
Comment ? À partir du moment où tu mets void* en début de ta
structure, tu dis au compilo que n'importe quel pointeur de données
peut aliaser ta structure. I.e. tu fais exactement el contraire de ce
que tu voudrais.
| typedef void* object;
| typedef object array;
| typedef object list;
|
| une list peut aller la ou un array est attendu, ce que je ne veux pas.
Mais ce que tu as proposé aupravant n'est pas une solution non plus !
Laurent Deniau writes:
| Antoine Leca wrote:
| > Laurent Deniau écrivit:
| >
| >>Typiquement mon ADT en C ressemble a ca:
| > Heu, excusez la question du Neu-neu, ADT, que es aco?
|
| Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien a
| savoir hormis les fonctions qui lui sont applicables (interface).
|
| >>#define D_ADT struct { void const * const _; } *
| > Dangereux cela, tu définis un structure anonyme (différente)
| > à chaque invocation de la macro; c'est peut-être ce que tu
| > veux, mais d'autres pourrait facilement se méprendre...
|
| C'est exactement ce que je veux. C'est pour palier au probleme des alias.
------------------------------------------------------------------------
Comment ? À partir du moment où tu mets void* en début de ta
structure, tu dis au compilo que n'importe quel pointeur de données
peut aliaser ta structure. I.e. tu fais exactement el contraire de ce
que tu voudrais.
| typedef void* object;
| typedef object array;
| typedef object list;
|
| une list peut aller la ou un array est attendu, ce que je ne veux pas.
Mais ce que tu as proposé aupravant n'est pas une solution non plus !
Antoine Leca wrote:Laurent Deniau écrivit:Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien
a savoir hormis les fonctions qui lui sont applicables (interface).
Ah. Quelque chose comme
struct adt;
Non.
typedef struct elem array[];
typedef struct list_elem list;
^^^^^^^^^
Ce n'est pas du tout ce que je veux.
Si tu y tiens,
typedef struct elem object;
Mais cela n'apporte rien, àmha.
Si.
Pour etre plus clair, voici un code qui montre le probleme:
<couic>
/* pas de warnings avec ce cas
struct adt;
typedef struct adt *list;
^^^^^
typedef struct adt *array;
Antoine Leca wrote:
Laurent Deniau écrivit:
Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien
a savoir hormis les fonctions qui lui sont applicables (interface).
Ah. Quelque chose comme
struct adt;
Non.
typedef struct elem array[];
typedef struct list_elem list;
^^^^^^^^^
Ce n'est pas du tout ce que je veux.
Si tu y tiens,
typedef struct elem object;
Mais cela n'apporte rien, àmha.
Si.
Pour etre plus clair, voici un code qui montre le probleme:
<couic>
/* pas de warnings avec ce cas
struct adt;
typedef struct adt *list;
^^^^^
typedef struct adt *array;
Antoine Leca wrote:Laurent Deniau écrivit:Abstract Data Type. Un objet dont l'utilisateur n'a absoluement rien
a savoir hormis les fonctions qui lui sont applicables (interface).
Ah. Quelque chose comme
struct adt;
Non.
typedef struct elem array[];
typedef struct list_elem list;
^^^^^^^^^
Ce n'est pas du tout ce que je veux.
Si tu y tiens,
typedef struct elem object;
Mais cela n'apporte rien, àmha.
Si.
Pour etre plus clair, voici un code qui montre le probleme:
<couic>
/* pas de warnings avec ce cas
struct adt;
typedef struct adt *list;
^^^^^
typedef struct adt *array;