En news:frh9si$5gu$, Marc Boyer va escriure:On 2008-03-15, candide wrote:
Non. Un compilateur normal va générer l'equivalent de
double foo(void){
return 8.0;
}
éventuellement précédé du mot-clé inline.
Voire même, va supprimer totalement le code généré, s'il s'aperçoit qu'il
n'y a aucun appel à la fonction foo dans tout le programme.
Là encore, il est possible que tout ceci soit remplacé par
void bar(double d) {}
(voire supprimé complètement). Même si les compilateurs courants ne vont pas
jusque là.
En news:frh9si$5gu$1@news.cict.fr, Marc Boyer va escriure:
On 2008-03-15, candide wrote:
Non. Un compilateur normal va générer l'equivalent de
double foo(void){
return 8.0;
}
éventuellement précédé du mot-clé inline.
Voire même, va supprimer totalement le code généré, s'il s'aperçoit qu'il
n'y a aucun appel à la fonction foo dans tout le programme.
Là encore, il est possible que tout ceci soit remplacé par
void bar(double d) {}
(voire supprimé complètement). Même si les compilateurs courants ne vont pas
jusque là.
En news:frh9si$5gu$, Marc Boyer va escriure:On 2008-03-15, candide wrote:
Non. Un compilateur normal va générer l'equivalent de
double foo(void){
return 8.0;
}
éventuellement précédé du mot-clé inline.
Voire même, va supprimer totalement le code généré, s'il s'aperçoit qu'il
n'y a aucun appel à la fonction foo dans tout le programme.
Là encore, il est possible que tout ceci soit remplacé par
void bar(double d) {}
(voire supprimé complètement). Même si les compilateurs courants ne vont pas
jusque là.
"int tab2[10][12];",
L'occurrence, il faudrait dire comment exactement ? "tab2" est une
variable de type tableau de *10x12 int* ?
2) Vous dites : « Ce pointeur est le premier argument de [], le
deuxième argument étant 2 ».
Mais ce qui me gêne, c'est qu'au final, tab[2] est une
expression de type int, et donc il doit bien avoir une opération
d'indirection (avec *) qui apparaît. Or dans ce que vous avez écrit,
j'ai l'impression que vous ne parlez pas de l'opérateur *.
Ces trois choses à ne pas confondre, si j'ai bien compris, c'est
lorsqu'on parle de type (int par exemple), il faut distinguer si l'on
parle :
1) du type d'une manière générale.
2) du type d'un objet (zone de la mémoire qui stocke des valeurs)
3) du type d'une valeur (qui peut parfois être le contenu d'un objet
et dans ce cas, le type de l'objet et le type de sa valeur sont
identiques)
"int tab2[10][12];",
L'occurrence, il faudrait dire comment exactement ? "tab2" est une
variable de type tableau de *10x12 int* ?
2) Vous dites : « Ce pointeur est le premier argument de [], le
deuxième argument étant 2 ».
Mais ce qui me gêne, c'est qu'au final, tab[2] est une
expression de type int, et donc il doit bien avoir une opération
d'indirection (avec *) qui apparaît. Or dans ce que vous avez écrit,
j'ai l'impression que vous ne parlez pas de l'opérateur *.
Ces trois choses à ne pas confondre, si j'ai bien compris, c'est
lorsqu'on parle de type (int par exemple), il faut distinguer si l'on
parle :
1) du type d'une manière générale.
2) du type d'un objet (zone de la mémoire qui stocke des valeurs)
3) du type d'une valeur (qui peut parfois être le contenu d'un objet
et dans ce cas, le type de l'objet et le type de sa valeur sont
identiques)
"int tab2[10][12];",
L'occurrence, il faudrait dire comment exactement ? "tab2" est une
variable de type tableau de *10x12 int* ?
2) Vous dites : « Ce pointeur est le premier argument de [], le
deuxième argument étant 2 ».
Mais ce qui me gêne, c'est qu'au final, tab[2] est une
expression de type int, et donc il doit bien avoir une opération
d'indirection (avec *) qui apparaît. Or dans ce que vous avez écrit,
j'ai l'impression que vous ne parlez pas de l'opérateur *.
Ces trois choses à ne pas confondre, si j'ai bien compris, c'est
lorsqu'on parle de type (int par exemple), il faut distinguer si l'on
parle :
1) du type d'une manière générale.
2) du type d'un objet (zone de la mémoire qui stocke des valeurs)
3) du type d'une valeur (qui peut parfois être le contenu d'un objet
et dans ce cas, le type de l'objet et le type de sa valeur sont
identiques)
Alors, spécialement pour Antoine:
void other(double *p);
double foo(void){
double p[10], q[10], r[10];
other(p+6); other(q+3); other(r+3);
return p[6]+q[3]+r[4];
}
En supposant que other() est défini dans une autre unité de
compilation. Comme le compilo ne sait pas ce que va faire other,
il ne peut pas optimiser grand chose, et même pas supprimer
des bouts de p, q et r, puisque other pourrait aller taper
dedans.
Par contre, dans le code exécutable de foo, on peut complètement
(enfin presque) oublier les tailles et adresse des début de p, q et r.
double x;
scanf("%d",&x);
vs
double t[6];
scanf("%d",t);
Alors, spécialement pour Antoine:
void other(double *p);
double foo(void){
double p[10], q[10], r[10];
other(p+6); other(q+3); other(r+3);
return p[6]+q[3]+r[4];
}
En supposant que other() est défini dans une autre unité de
compilation. Comme le compilo ne sait pas ce que va faire other,
il ne peut pas optimiser grand chose, et même pas supprimer
des bouts de p, q et r, puisque other pourrait aller taper
dedans.
Par contre, dans le code exécutable de foo, on peut complètement
(enfin presque) oublier les tailles et adresse des début de p, q et r.
double x;
scanf("%d",&x);
vs
double t[6];
scanf("%d",t);
Alors, spécialement pour Antoine:
void other(double *p);
double foo(void){
double p[10], q[10], r[10];
other(p+6); other(q+3); other(r+3);
return p[6]+q[3]+r[4];
}
En supposant que other() est défini dans une autre unité de
compilation. Comme le compilo ne sait pas ce que va faire other,
il ne peut pas optimiser grand chose, et même pas supprimer
des bouts de p, q et r, puisque other pourrait aller taper
dedans.
Par contre, dans le code exécutable de foo, on peut complètement
(enfin presque) oublier les tailles et adresse des début de p, q et r.
double x;
scanf("%d",&x);
vs
double t[6];
scanf("%d",t);
"int tab2[10][12];",
L'occurrence, il faudrait dire comment exactement ? "tab2" est une
variable de type tableau de *10x12 int* ?
Non : les tableaux multi-dimensionnels n'existent pas en C. tab2 est le nom
d'une variable de type tableau de 12 tableaux de 10 entiers.
2) Vous dites : « Ce pointeur est le premier argument de [], le
deuxième argument étant 2 ».
[] est un opérateur binaire (comme *, sauf qu'il a une forme moins
classique), donc il a besoin de deux opérandes (argument dans la prose de
JM) pour opérer. Le premier est un pointeur, le second un entier.
Le résultat est du type vers lequel pointe le pointeur (ici int).
Mais ce qui me gêne, c'est qu'au final, tab[2] est une
expression de type int, et donc il doit bien avoir une opération
d'indirection (avec *) qui apparaît. Or dans ce que vous avez écrit,
j'ai l'impression que vous ne parlez pas de l'opérateur *.
Tout se passe comme si au lieu de E1[E2], on écrivait (*((E1)+(E2))). C'est
juste un raccourci bien utile (et qui démontre qu'on est pas en Lisp).
Ces trois choses à ne pas confondre, si j'ai bien compris, c'est
lorsqu'on parle de type (int par exemple), il faut distinguer si l'on
parle :
1) du type d'une manière générale.
2) du type d'un objet (zone de la mémoire qui stocke des valeurs)
3) du type d'une valeur (qui peut parfois être le contenu d'un objet
et dans ce cas, le type de l'objet et le type de sa valeur sont
identiques)
Je verrais plutôt
2) du type d'un nom (identifiant)
3) du type d'une expression
Le troisième est une clause de style ; par contre, au niveau du deuxième il
y a plus de différence : un nom désigne un objet, mais les objets ne sont
pas tous identifiables par des noms.
"int tab2[10][12];",
L'occurrence, il faudrait dire comment exactement ? "tab2" est une
variable de type tableau de *10x12 int* ?
Non : les tableaux multi-dimensionnels n'existent pas en C. tab2 est le nom
d'une variable de type tableau de 12 tableaux de 10 entiers.
2) Vous dites : « Ce pointeur est le premier argument de [], le
deuxième argument étant 2 ».
[] est un opérateur binaire (comme *, sauf qu'il a une forme moins
classique), donc il a besoin de deux opérandes (argument dans la prose de
JM) pour opérer. Le premier est un pointeur, le second un entier.
Le résultat est du type vers lequel pointe le pointeur (ici int).
Mais ce qui me gêne, c'est qu'au final, tab[2] est une
expression de type int, et donc il doit bien avoir une opération
d'indirection (avec *) qui apparaît. Or dans ce que vous avez écrit,
j'ai l'impression que vous ne parlez pas de l'opérateur *.
Tout se passe comme si au lieu de E1[E2], on écrivait (*((E1)+(E2))). C'est
juste un raccourci bien utile (et qui démontre qu'on est pas en Lisp).
Ces trois choses à ne pas confondre, si j'ai bien compris, c'est
lorsqu'on parle de type (int par exemple), il faut distinguer si l'on
parle :
1) du type d'une manière générale.
2) du type d'un objet (zone de la mémoire qui stocke des valeurs)
3) du type d'une valeur (qui peut parfois être le contenu d'un objet
et dans ce cas, le type de l'objet et le type de sa valeur sont
identiques)
Je verrais plutôt
2) du type d'un nom (identifiant)
3) du type d'une expression
Le troisième est une clause de style ; par contre, au niveau du deuxième il
y a plus de différence : un nom désigne un objet, mais les objets ne sont
pas tous identifiables par des noms.
"int tab2[10][12];",
L'occurrence, il faudrait dire comment exactement ? "tab2" est une
variable de type tableau de *10x12 int* ?
Non : les tableaux multi-dimensionnels n'existent pas en C. tab2 est le nom
d'une variable de type tableau de 12 tableaux de 10 entiers.
2) Vous dites : « Ce pointeur est le premier argument de [], le
deuxième argument étant 2 ».
[] est un opérateur binaire (comme *, sauf qu'il a une forme moins
classique), donc il a besoin de deux opérandes (argument dans la prose de
JM) pour opérer. Le premier est un pointeur, le second un entier.
Le résultat est du type vers lequel pointe le pointeur (ici int).
Mais ce qui me gêne, c'est qu'au final, tab[2] est une
expression de type int, et donc il doit bien avoir une opération
d'indirection (avec *) qui apparaît. Or dans ce que vous avez écrit,
j'ai l'impression que vous ne parlez pas de l'opérateur *.
Tout se passe comme si au lieu de E1[E2], on écrivait (*((E1)+(E2))). C'est
juste un raccourci bien utile (et qui démontre qu'on est pas en Lisp).
Ces trois choses à ne pas confondre, si j'ai bien compris, c'est
lorsqu'on parle de type (int par exemple), il faut distinguer si l'on
parle :
1) du type d'une manière générale.
2) du type d'un objet (zone de la mémoire qui stocke des valeurs)
3) du type d'une valeur (qui peut parfois être le contenu d'un objet
et dans ce cas, le type de l'objet et le type de sa valeur sont
identiques)
Je verrais plutôt
2) du type d'un nom (identifiant)
3) du type d'une expression
Le troisième est une clause de style ; par contre, au niveau du deuxième il
y a plus de différence : un nom désigne un objet, mais les objets ne sont
pas tous identifiables par des noms.
En news:, Marc Boyer va escriure:Alors, spécialement pour Antoine:
void other(double *p);
double foo(void){
double p[10], q[10], r[10];
other(p+6); other(q+3); other(r+3);
return p[6]+q[3]+r[4];
}
En supposant que other() est défini dans une autre unité de
compilation. Comme le compilo ne sait pas ce que va faire other,
En fait le C n'oblige pas à ce que la compilation soit complètement
indépendante : donc il est _possible_ que le compilateur puisse avoir des
informations sur other() même s'il est compilé à part : par exemple, il
pourrait faire la supposition que other() modifie, ou pas, le tableau
sous-jaçant à son argument ; et générer deux versions de foo(), l'une qui
appelerait other$1 (où les autres adresses ne seraient pas modifiées, et
dont le protype serait réécrit double other$1(void)) ; et une autre moins
agressive, où p est supposé modifié y compris ailleurs.
Et de générer
inline double foo$1(void) {
return other$1() .+ other$1() .+ other$1(); }
(où .+ représente l'opérateur non commutatif, qui évalue d'abord à gauche
puis à droite) ; et
double foo$2(void){
double p[10], q[10], r[10];
other$2(p+6, p, <double[10]>);
other$2(q+3, q, <double[10]>);
other$2(r+3, r, <double[10]>);
return p[6]+q[3]+r[4];
}
(j'ai explicité les arguments pour pouvoir réaliser la vérification complète
de la conformité des opérations dans other$2.) Il ne restera plus à
l'éditeur de liens qu'à choisir entre foo$1 et foo$2 en fonction de la
version réellement fournie pour other(), et peut-être du niveau de debug
désiré.
il ne peut pas optimiser grand chose, et même pas supprimer
des bouts de p, q et r, puisque other pourrait aller taper
dedans.
Par contre, dans le code exécutable de foo, on peut complètement
(enfin presque) oublier les tailles et adresse des début de p, q et r.
Euh, dans le cas other$2 où te sembles te placer, il faut quand même les
allouer et les supprimer...
double x;
scanf("%d",&x);
u.b.
OK, je sais que c'est beaucoup plus facile de pinailler que de fournir des
solutions, donc je vais arrêter de faire l'idiot.
D'ailleurs je pense que ce
que tu voulais démontrer initialement (que le compilateur fait une
différence très grande entre le tableau d'une part, et son adresse d'autre
part) devrait être maintenant assez clair.
En news:slrnftt07n.mbc.Marc.Boyer@ubu.enseeiht.fr, Marc Boyer va escriure:
Alors, spécialement pour Antoine:
void other(double *p);
double foo(void){
double p[10], q[10], r[10];
other(p+6); other(q+3); other(r+3);
return p[6]+q[3]+r[4];
}
En supposant que other() est défini dans une autre unité de
compilation. Comme le compilo ne sait pas ce que va faire other,
En fait le C n'oblige pas à ce que la compilation soit complètement
indépendante : donc il est _possible_ que le compilateur puisse avoir des
informations sur other() même s'il est compilé à part : par exemple, il
pourrait faire la supposition que other() modifie, ou pas, le tableau
sous-jaçant à son argument ; et générer deux versions de foo(), l'une qui
appelerait other$1 (où les autres adresses ne seraient pas modifiées, et
dont le protype serait réécrit double other$1(void)) ; et une autre moins
agressive, où p est supposé modifié y compris ailleurs.
Et de générer
inline double foo$1(void) {
return other$1() .+ other$1() .+ other$1(); }
(où .+ représente l'opérateur non commutatif, qui évalue d'abord à gauche
puis à droite) ; et
double foo$2(void){
double p[10], q[10], r[10];
other$2(p+6, p, <double[10]>);
other$2(q+3, q, <double[10]>);
other$2(r+3, r, <double[10]>);
return p[6]+q[3]+r[4];
}
(j'ai explicité les arguments pour pouvoir réaliser la vérification complète
de la conformité des opérations dans other$2.) Il ne restera plus à
l'éditeur de liens qu'à choisir entre foo$1 et foo$2 en fonction de la
version réellement fournie pour other(), et peut-être du niveau de debug
désiré.
il ne peut pas optimiser grand chose, et même pas supprimer
des bouts de p, q et r, puisque other pourrait aller taper
dedans.
Par contre, dans le code exécutable de foo, on peut complètement
(enfin presque) oublier les tailles et adresse des début de p, q et r.
Euh, dans le cas other$2 où te sembles te placer, il faut quand même les
allouer et les supprimer...
double x;
scanf("%d",&x);
u.b.
OK, je sais que c'est beaucoup plus facile de pinailler que de fournir des
solutions, donc je vais arrêter de faire l'idiot.
D'ailleurs je pense que ce
que tu voulais démontrer initialement (que le compilateur fait une
différence très grande entre le tableau d'une part, et son adresse d'autre
part) devrait être maintenant assez clair.
En news:, Marc Boyer va escriure:Alors, spécialement pour Antoine:
void other(double *p);
double foo(void){
double p[10], q[10], r[10];
other(p+6); other(q+3); other(r+3);
return p[6]+q[3]+r[4];
}
En supposant que other() est défini dans une autre unité de
compilation. Comme le compilo ne sait pas ce que va faire other,
En fait le C n'oblige pas à ce que la compilation soit complètement
indépendante : donc il est _possible_ que le compilateur puisse avoir des
informations sur other() même s'il est compilé à part : par exemple, il
pourrait faire la supposition que other() modifie, ou pas, le tableau
sous-jaçant à son argument ; et générer deux versions de foo(), l'une qui
appelerait other$1 (où les autres adresses ne seraient pas modifiées, et
dont le protype serait réécrit double other$1(void)) ; et une autre moins
agressive, où p est supposé modifié y compris ailleurs.
Et de générer
inline double foo$1(void) {
return other$1() .+ other$1() .+ other$1(); }
(où .+ représente l'opérateur non commutatif, qui évalue d'abord à gauche
puis à droite) ; et
double foo$2(void){
double p[10], q[10], r[10];
other$2(p+6, p, <double[10]>);
other$2(q+3, q, <double[10]>);
other$2(r+3, r, <double[10]>);
return p[6]+q[3]+r[4];
}
(j'ai explicité les arguments pour pouvoir réaliser la vérification complète
de la conformité des opérations dans other$2.) Il ne restera plus à
l'éditeur de liens qu'à choisir entre foo$1 et foo$2 en fonction de la
version réellement fournie pour other(), et peut-être du niveau de debug
désiré.
il ne peut pas optimiser grand chose, et même pas supprimer
des bouts de p, q et r, puisque other pourrait aller taper
dedans.
Par contre, dans le code exécutable de foo, on peut complètement
(enfin presque) oublier les tailles et adresse des début de p, q et r.
Euh, dans le cas other$2 où te sembles te placer, il faut quand même les
allouer et les supprimer...
double x;
scanf("%d",&x);
u.b.
OK, je sais que c'est beaucoup plus facile de pinailler que de fournir des
solutions, donc je vais arrêter de faire l'idiot.
D'ailleurs je pense que ce
que tu voulais démontrer initialement (que le compilateur fait une
différence très grande entre le tableau d'une part, et son adresse d'autre
part) devrait être maintenant assez clair.
"int tab2[10][12];",
L'occurrence, il faudrait dire comment exactement ? "tab2" est une
variable de type tableau de *10x12 int* ?
Non : les tableaux multi-dimensionnels n'existent pas en C. tab2 est
le nom
d'une variable de type tableau de 12 tableaux de 10 entiers.
Alors, est-ce que par hasard ce ne serait pas plutôt « une variable de
type tableau de 10 tableaux de 12 entiers » ?
"int tab2[10][12];",
L'occurrence, il faudrait dire comment exactement ? "tab2" est une
variable de type tableau de *10x12 int* ?
Non : les tableaux multi-dimensionnels n'existent pas en C. tab2 est
le nom
d'une variable de type tableau de 12 tableaux de 10 entiers.
Alors, est-ce que par hasard ce ne serait pas plutôt « une variable de
type tableau de 10 tableaux de 12 entiers » ?
"int tab2[10][12];",
L'occurrence, il faudrait dire comment exactement ? "tab2" est une
variable de type tableau de *10x12 int* ?
Non : les tableaux multi-dimensionnels n'existent pas en C. tab2 est
le nom
d'une variable de type tableau de 12 tableaux de 10 entiers.
Alors, est-ce que par hasard ce ne serait pas plutôt « une variable de
type tableau de 10 tableaux de 12 entiers » ?
N'ais-je pas convaincu que les gens qui savaient déjà ?
Rassure-moi, on peut quand même faire honnêtement du C sans savoir
N'ais-je pas convaincu que les gens qui savaient déjà ?
Rassure-moi, on peut quand même faire honnêtement du C sans savoir
N'ais-je pas convaincu que les gens qui savaient déjà ?
Rassure-moi, on peut quand même faire honnêtement du C sans savoir
Non : les tableaux multi-dimensionnels n'existent pas en C. tab2 est
le nom
d'une variable de type tableau de 12 tableaux de 10 entiers.
Alors, est-ce que par hasard ce ne serait pas plutôt « une variable de
type tableau de 10 tableaux de 12 entiers » ?
Pardon d'insister, mais pourrais-je avoir un confirmation/infirmation de
ceci ?
Non : les tableaux multi-dimensionnels n'existent pas en C. tab2 est
le nom
d'une variable de type tableau de 12 tableaux de 10 entiers.
Alors, est-ce que par hasard ce ne serait pas plutôt « une variable de
type tableau de 10 tableaux de 12 entiers » ?
Pardon d'insister, mais pourrais-je avoir un confirmation/infirmation de
ceci ?
Non : les tableaux multi-dimensionnels n'existent pas en C. tab2 est
le nom
d'une variable de type tableau de 12 tableaux de 10 entiers.
Alors, est-ce que par hasard ce ne serait pas plutôt « une variable de
type tableau de 10 tableaux de 12 entiers » ?
Pardon d'insister, mais pourrais-je avoir un confirmation/infirmation de
ceci ?
-------------------------
§5.4.2
Multidimensional arrays are declared "arrays of arrays", such as in the
declaration
int matrix[12][10];
wich declares to be a 12-by-10 element array of int.
-------------------------
--------------------8<----------------------------------------
6.5.2.1 Array subscripting
4 EXAMPLE Consider the array object defined by the declaration
int x[3][5];
Here x is a 3 ´ 5 array of ints; more precisely, x is an array of three
element objects, each of which is an array of five ints.
-------------------->8----------------------------------------
-------------------------
§5.4.2
Multidimensional arrays are declared "arrays of arrays", such as in the
declaration
int matrix[12][10];
wich declares to be a 12-by-10 element array of int.
-------------------------
--------------------8<----------------------------------------
6.5.2.1 Array subscripting
4 EXAMPLE Consider the array object defined by the declaration
int x[3][5];
Here x is a 3 ´ 5 array of ints; more precisely, x is an array of three
element objects, each of which is an array of five ints.
-------------------->8----------------------------------------
-------------------------
§5.4.2
Multidimensional arrays are declared "arrays of arrays", such as in the
declaration
int matrix[12][10];
wich declares to be a 12-by-10 element array of int.
-------------------------
--------------------8<----------------------------------------
6.5.2.1 Array subscripting
4 EXAMPLE Consider the array object defined by the declaration
int x[3][5];
Here x is a 3 ´ 5 array of ints; more precisely, x is an array of three
element objects, each of which is an array of five ints.
-------------------->8----------------------------------------
--------------------8<----------------------------------------
6.5.2.1 Array subscripting
4 EXAMPLE Consider the array object defined by the declaration
int x[3][5];
Here x is a 3 ´ 5 array of ints; more precisely, x is an array of three
element objects, each of which is an array of five ints.
-------------------->8----------------------------------------
Oui, la norme est capable de donner des définitions et des exemples
clairs. Et ce n'est pas rare.
--------------------8<----------------------------------------
6.5.2.1 Array subscripting
4 EXAMPLE Consider the array object defined by the declaration
int x[3][5];
Here x is a 3 ´ 5 array of ints; more precisely, x is an array of three
element objects, each of which is an array of five ints.
-------------------->8----------------------------------------
Oui, la norme est capable de donner des définitions et des exemples
clairs. Et ce n'est pas rare.
--------------------8<----------------------------------------
6.5.2.1 Array subscripting
4 EXAMPLE Consider the array object defined by the declaration
int x[3][5];
Here x is a 3 ´ 5 array of ints; more precisely, x is an array of three
element objects, each of which is an array of five ints.
-------------------->8----------------------------------------
Oui, la norme est capable de donner des définitions et des exemples
clairs. Et ce n'est pas rare.