1

Si vous avez 30s, trouvez quelles sont les fonctions suivantes
qui vont faire tilter votre compilateur favori.

Question bonus : expliquez pourquoi.

struct toto;

void f0 (const struct toto *tab[]);
void g0 (struct toto *tab[])
{
  f0 (tab);
}

void f1 (const struct toto *const tab[]);
void g1 (struct toto *tab[])
{
  f1 (tab);
}

void f2 (const struct toto *const *const tab);
void g2 (struct toto *tab[])
{
  f2 (tab);
}

void f3 (struct toto *const tab[]);
void g3 (struct toto *tab[])
{
  f3 (tab);
}

void f4 (struct toto *const *const tab);
void g4 (struct toto *tab[])
{
  f4 (tab);
}

void f5 (const struct toto * *const tab);
void g5 (struct toto *tab[])
{
  f5 (tab);
}

void f6 (struct toto * *const tab);
void g6 (struct toto *tab[])
{
  f6 (tab);
}

2

sad Je n'en vois aucune mourn
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

3

oui: 0 1 2 5 car on dit explicitement que tab est const
non: 3 car tab[42] est const mais pas tab
non: 4 car tab[42] et tab[42][42] sont const mais pas tab
non: 6 car tab[42][42] est const mais pas tab (ni tab[42] mais on s'en fout)

c'est ça?
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

4

Non c'est exactement le contraire gni

5

Mais si vous me demandez pourquoi, la je ne peux repondre #tss#
Certains const peuvent neanmoins etre explique:
http://groups.google.fr/group/fr.comp.lang.c/browse_thread/thread/b65b15b707849fd4/7e8c28551b4ddfd8?q=%22Patrick+Pelissier+%22&rnum=2&hl=fr#7e8c28551b4ddfd8

6

quand je dis oui, c'est oui ça fait tilt
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

7

vérification:
(benjamin@commandant:~/merdier)►gcc -c tilt.c
tilt.c: Dans la fonction « g0 »:
tilt.c:6: attention : passage de l'argument n°1 de « f0 » d'un type pointeur incompatible
tilt.c: Dans la fonction « g1 »:
tilt.c:12: attention : passage de l'argument n°1 de « f1 » d'un type pointeur incompatible
tilt.c: Dans la fonction « g2 »:
tilt.c:18: attention : passage de l'argument n°1 de « f2 » d'un type pointeur incompatible
tilt.c: Dans la fonction « g5 »:
tilt.c:36: attention : passage de l'argument n°1 de « f5 » d'un type pointeur incompatible

tu obtiens vraiment l'opposé?
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

8

C'etait pas clair ta reponse.
A noter que ICC ne repond pas la meme chose:
latour pelissip 55 % /localdisk/icc/opt/intel_cc_80/bin/icc -c tutu.c 
tutu.c(6): warning #167: argument of type "struct toto **" is incompatible with parameter of type "const struct toto **"
    f0 (tab);
        ^

tutu.c(36): warning #167: argument of type "struct toto **" is incompatible with parameter of type "const struct toto **const"
    f5 (tab);
        ^

9

Perso j'estime que ICC a raison, mais je ne suis pas sur que la norme ne donne pas raison a GCC smile

10

c'est étonnant qu'il ne gueule pas pour f1
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

11

(je dis ça vu qu'il le dit pour f0)
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

12

tu peux expliciter ton point de vue par rapport à ICC ?
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

13

const struct toto *const tab[] = const struct toto *const *tab.
Et en fait c'est ce const                                             ^^

qui fait que, a mon avis, ce cast est parfaitement legal.
En effet, le coup du cast refuse du char ** vers const char **est parfaitement ok.
Mais si on met un const en plus: const char *const *, la ca devrait passer car on le fait en 2 etapes:

La norme dit qu'il y a une conversion automatique
toto * p
vers
const|volatile toto * p
cela ne s'étend ni à (1)
toto ** p
vers
const|volatile toto ** p
et ni à (2)
toto (*p) [N]
vers
const|volatile toto (*p)[N]


Le probleme est que toto * --> const toto * est ok
Mais pas toto ** vers const toto ** parce que le const n'est pas au bon endroit.
toto ** vers toto *const* est ok. toto * vers const toto * est ok.
En faisant 2 etapes, on passe de toto ** vers const toto *const*.
(Ok pas clair grin)

14

Mais je ne suis pas sur que ca soit ok pour la norme. Faudrait que je la lise.

15

je comprends, du coup f1 et f2 sont valides du point de vue du compilateur,
mais apparemment pas du point de vue de la norme!
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

16

Pas sur. C'est peut etre un bug de GCC. A voir.

17

ou peut être que gcc vérifie ça par niveau de pointeur sans vérifier globalement le type
et du coup il ne peut pas assurer la validité (indépendemment de la norme)
edit: cross >_<
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

18

Oue. Mais bon. Je vais demander a des experts avant

19

oui, interroge ton commité d'experts!
(je dois passer prendre des bouquins à la bibli de la fac, je regarderai la norme si j'ai le temps)
ou bien tu ajoutes des casts explicites dans ton code happy
parce que ce genre de types quand tu dois relire ton code pour savoir exactement ce qu'il fait, c'est la joie grin
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

20

Oue tritop

21

Extrait de la norme.

6.3.2.3 Pointers

[#1] A pointer to void may be converted to or from a pointer
to any incomplete or object type. A pointer to any
incomplete or object type may be converted to a pointer to
void and back again; the result shall compare equal to the
original pointer.

[#2] For any qualifier q, a pointer to a non-q-qualified
type may be converted to a pointer to the q-qualified
version of the type; the values stored in the original and
converted pointers shall compare equal.

[#3] An integer constant expression with the value 0, or
such an expression cast to type void *, is called a null
pointer constant.48) If a null pointer constant is |
converted to a pointer type, the resulting pointer, called a
null pointer, is guaranteed to compare unequal to a pointer
to any object or function.

[#4] Conversion of a null pointer to another pointer type
yields a null pointer of that type. Any two null pointers
shall compare equal.

[#5] An integer may be converted to any pointer type. |
Except as previously specified, the result is
implementation-defined, might not be properly aligned, and
might not point to an entity of the referenced type.49)

[#6] Any pointer type may be converted to an integer type. |
Except as previously specified, the result is
implementation-defined. If the result cannot be represented
in the integer type, the behavior is undefined. The result
need not be in the range of values of any integer type.

[#7] A pointer to an object or incomplete type may be
converted to a pointer to a different object or incomplete
type. If the resulting pointer is not correctly aligned50)
for the pointed-to type, the behavior is undefined.
Otherwise, when converted back again, the result shall
compare equal to the original pointer. When a pointer to an
object is converted to a pointer to a character type, the
result points to the lowest addressed byte of the object.

Successive increments of the result, up to the size of the
object, yield pointers to the remaining bytes of the object.

[#8] A pointer to a function of one type may be converted to
a pointer to a function of another type and back again; the
result shall compare equal to the original pointer. If a
converted pointer is used to call a function whose type is
not compatible with the pointed-to type, the behavior is
undefined.

Forward references: cast operators (6.5.4), equality
operators (6.5.9), simple assignment (6.5.16.1).


Le #2 me donne raison.

22

ben nan, c pas parce qu'on peut convertir un "machin *" en "const machin *" que le reste marche pour les conversions implicites... sauf si la norme ne spécifie pas quand l'implémentation doit faire un warning, mais ca m'étonnerait what

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

23

Si tu veux. Mais tu passes a cote du probleme. Le probleme est machin ** en const machin *const*.

24

du #2 moi je déduis qu'à l'appel,
si tab n'est pas const, il est converti en const, je vois rien qui ne parle des autres niveaux d'indirection

mais bon, je n'ai pê rien compris
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

25

Ben "const toto ** est un non-q-qualified type, non ? Mais pas const toto *

26

PpHd :
Si tu veux. Mais tu passes a cote du probleme. Le probleme est machin ** en const machin *const*.

ben nan, justement, c'est toi qui passes a coté du probleme cécuikidikiyé, puisque ce n'est pas ce dont parle ce que tu cites dans la norme : le paragraphe que tu cites dit qu'on peut convertir "machin **" en "machin *const*", mais ne parle pas du tout de "const machin *const*"...

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

27

Ben la c'est clair au moins ! Mais je ne suis pas sur d'etre d'accord.

28

oui mais ça ne comprends pas la donnée pointée,
certes on déqualifie le pointeur mais pas la donnée pointée,
donc une série de pointeurs const sera déqualifiée en une série de pointeurs non const mais la donnée au bout restera const

edit: tiens encore un cross
avatar
fabetal_ > Hier, je me suis fait monter par un pote
redangel > et en chevals, ça donne quoi?
Nil> OMG I think I'm gay

29

BookeldOr :
oui mais ça ne comprends pas la donnée pointée,
certes on déqualifie le pointeur mais pas la donnée pointée,
donc une série de pointeurs const sera déqualifiée en une série de pointeurs non const mais la donnée au bout restera const

euh c'est pas du tout ca le pb, c'est pas déqualifier un pointeur mais ajouter un qualificateur aux données pointées tongue


PpHd> pkoi ?

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

30

Ok j'y ai reflechi hier soir. J'avais tord. Vous aviez raison. GCC est ok avec la norme. Mais je persiste a penser que ce sont des warnings a la con tongue