void Fct(long ¶m = 0);
{
param *=2;
}
si je fais :
---
int a = 3;
Fct(a);
---
Je comprend que ma variable locale 'a' a été passée par référ ence à la
fonction Fct laquelle a pu accéder à son contenu.
J'ai été surpris de voir que mon compilateur ne bronchait pas quand j'ai
écrit Fct() !
void Fct(long ¶m = 0);
{
param *=2;
}
si je fais :
---
int a = 3;
Fct(a);
---
Je comprend que ma variable locale 'a' a été passée par référ ence à la
fonction Fct laquelle a pu accéder à son contenu.
J'ai été surpris de voir que mon compilateur ne bronchait pas quand j'ai
écrit Fct() !
void Fct(long ¶m = 0);
{
param *=2;
}
si je fais :
---
int a = 3;
Fct(a);
---
Je comprend que ma variable locale 'a' a été passée par référ ence à la
fonction Fct laquelle a pu accéder à son contenu.
J'ai été surpris de voir que mon compilateur ne bronchait pas quand j'ai
écrit Fct() !
Salut,
soit le prototype d'une fonction :
---
void Fct(long ¶m = 0);
---
Mais si je fais ça :
Fct();
Quelle référence de variable Fct reçoit-elle ? un temporaire ?
si oui, l'appel à Fct(a) passe-t-il aussi par un temporaire ? si oui
pourquoi ?
J'ai été surpris de voir que mon compilateur ne bronchait pas quand j'ai
écrit Fct() !
Salut,
soit le prototype d'une fonction :
---
void Fct(long ¶m = 0);
---
Mais si je fais ça :
Fct();
Quelle référence de variable Fct reçoit-elle ? un temporaire ?
si oui, l'appel à Fct(a) passe-t-il aussi par un temporaire ? si oui
pourquoi ?
J'ai été surpris de voir que mon compilateur ne bronchait pas quand j'ai
écrit Fct() !
Salut,
soit le prototype d'une fonction :
---
void Fct(long ¶m = 0);
---
Mais si je fais ça :
Fct();
Quelle référence de variable Fct reçoit-elle ? un temporaire ?
si oui, l'appel à Fct(a) passe-t-il aussi par un temporaire ? si oui
pourquoi ?
J'ai été surpris de voir que mon compilateur ne bronchait pas quand j'ai
écrit Fct() !
PurL wrote:
void Fct(long ¶m = 0);
Ça ne devrait même pas compiler (et ça ne compile pas chez moi
avec gcc) ! Si l'argument (y compris un argument par défaut)
pour un paramètre de référence n'est pas une "l-value", il
faut absolument que le type référencé par ce paramètre soit
qualifié "const" - et dans ce cas-là, le compilateur crée
effectivement un temporaire du bon type et l'initialise avec
l'argument.
void Fct(long const& param = 0);
serait donc légal - mais ne permet pas de modifier 'param' ;
et particulier, on ne peut pas faire
{
param *=2;
}
si je fais :
---
int a = 3;
Fct(a);
---
Je comprend que ma variable locale 'a' a été passée par
référence à la fonction Fct laquelle a pu accéder à son
contenu.
Pareil - ça ne passe qu'avec "void Fct(long const& param)"
(création d'un temporaire du type "long" qui est initialisé
avec "3") ou bien avec "void Fct(int& param)" (passage de "a"
par référence, les modifications faites par "Fct" sur ce
paramètre sont donc répercutées dans "a")
J'ai été surpris de voir que mon compilateur ne bronchait pas
quand j'ai écrit Fct() !
C'est quel compilateur ?
PurL wrote:
void Fct(long ¶m = 0);
Ça ne devrait même pas compiler (et ça ne compile pas chez moi
avec gcc) ! Si l'argument (y compris un argument par défaut)
pour un paramètre de référence n'est pas une "l-value", il
faut absolument que le type référencé par ce paramètre soit
qualifié "const" - et dans ce cas-là, le compilateur crée
effectivement un temporaire du bon type et l'initialise avec
l'argument.
void Fct(long const& param = 0);
serait donc légal - mais ne permet pas de modifier 'param' ;
et particulier, on ne peut pas faire
{
param *=2;
}
si je fais :
---
int a = 3;
Fct(a);
---
Je comprend que ma variable locale 'a' a été passée par
référence à la fonction Fct laquelle a pu accéder à son
contenu.
Pareil - ça ne passe qu'avec "void Fct(long const& param)"
(création d'un temporaire du type "long" qui est initialisé
avec "3") ou bien avec "void Fct(int& param)" (passage de "a"
par référence, les modifications faites par "Fct" sur ce
paramètre sont donc répercutées dans "a")
J'ai été surpris de voir que mon compilateur ne bronchait pas
quand j'ai écrit Fct() !
C'est quel compilateur ?
PurL wrote:
void Fct(long ¶m = 0);
Ça ne devrait même pas compiler (et ça ne compile pas chez moi
avec gcc) ! Si l'argument (y compris un argument par défaut)
pour un paramètre de référence n'est pas une "l-value", il
faut absolument que le type référencé par ce paramètre soit
qualifié "const" - et dans ce cas-là, le compilateur crée
effectivement un temporaire du bon type et l'initialise avec
l'argument.
void Fct(long const& param = 0);
serait donc légal - mais ne permet pas de modifier 'param' ;
et particulier, on ne peut pas faire
{
param *=2;
}
si je fais :
---
int a = 3;
Fct(a);
---
Je comprend que ma variable locale 'a' a été passée par
référence à la fonction Fct laquelle a pu accéder à son
contenu.
Pareil - ça ne passe qu'avec "void Fct(long const& param)"
(création d'un temporaire du type "long" qui est initialisé
avec "3") ou bien avec "void Fct(int& param)" (passage de "a"
par référence, les modifications faites par "Fct" sur ce
paramètre sont donc répercutées dans "a")
J'ai été surpris de voir que mon compilateur ne bronchait pas
quand j'ai écrit Fct() !
C'est quel compilateur ?
Effectivement mon exemple ne compile pas non plus chez moi.
Désolé j'ai été un peu vite en besogne :(
Mais au départ, j'avais le probleme avec AnsiString à la place
de long et c'est qu'en j'écris :
void Fct(AnsiString &a = (AnsiString)"");
que le compilateur ne bronche pas, mais je pense que dans ce
cas, si je ne précise pas le parametre dans l'appel de ma
fonction Fct, un temporaire de type AnsiString initialisé avec
"" est créé et assigné (du moins sa référence) à ma variable
'a'.
Effectivement mon exemple ne compile pas non plus chez moi.
Désolé j'ai été un peu vite en besogne :(
Mais au départ, j'avais le probleme avec AnsiString à la place
de long et c'est qu'en j'écris :
void Fct(AnsiString &a = (AnsiString)"");
que le compilateur ne bronche pas, mais je pense que dans ce
cas, si je ne précise pas le parametre dans l'appel de ma
fonction Fct, un temporaire de type AnsiString initialisé avec
"" est créé et assigné (du moins sa référence) à ma variable
'a'.
Effectivement mon exemple ne compile pas non plus chez moi.
Désolé j'ai été un peu vite en besogne :(
Mais au départ, j'avais le probleme avec AnsiString à la place
de long et c'est qu'en j'écris :
void Fct(AnsiString &a = (AnsiString)"");
que le compilateur ne bronche pas, mais je pense que dans ce
cas, si je ne précise pas le parametre dans l'appel de ma
fonction Fct, un temporaire de type AnsiString initialisé avec
"" est créé et assigné (du moins sa référence) à ma variable
'a'.
PurL wrote:
soit le prototype d'une fonction :
---
void Fct(long ¶m = 0);
---
Euh, quel compilateur accepte ca ?
C'est pas autorisé par la norme. Une lvalue est requise pour
initialiser une référence, donc ce code est incorrect.
Avec un passage par adresse, et un long* param = 0, ca devient
correct. Mais pas en passage par référence. Par contre dans ce
cas le code de la fonction est à changer, et un test sur NULL
à faire avant de faire toute opération de déréférencement sur
param.
Mais si je fais ça :
Fct();
Quelle référence de variable Fct reçoit-elle ? un temporaire ?
si oui, l'appel à Fct(a) passe-t-il aussi par un temporaire ?
si oui pourquoi ?
L'appel à Fct(a) n'a pas à ma connaissance à passer par un
temporaire, vu que c'est un passage par référence.
Et vu que le code d'origine n'est pas conforme, je ne peux pas
répondre à la première question.
J'ai été surpris de voir que mon compilateur ne bronchait pas
quand j'ai écrit Fct() !
Et moi je serai curieux de savoir qui accepte le code du
prototype de la fonction.
PurL wrote:
soit le prototype d'une fonction :
---
void Fct(long ¶m = 0);
---
Euh, quel compilateur accepte ca ?
C'est pas autorisé par la norme. Une lvalue est requise pour
initialiser une référence, donc ce code est incorrect.
Avec un passage par adresse, et un long* param = 0, ca devient
correct. Mais pas en passage par référence. Par contre dans ce
cas le code de la fonction est à changer, et un test sur NULL
à faire avant de faire toute opération de déréférencement sur
param.
Mais si je fais ça :
Fct();
Quelle référence de variable Fct reçoit-elle ? un temporaire ?
si oui, l'appel à Fct(a) passe-t-il aussi par un temporaire ?
si oui pourquoi ?
L'appel à Fct(a) n'a pas à ma connaissance à passer par un
temporaire, vu que c'est un passage par référence.
Et vu que le code d'origine n'est pas conforme, je ne peux pas
répondre à la première question.
J'ai été surpris de voir que mon compilateur ne bronchait pas
quand j'ai écrit Fct() !
Et moi je serai curieux de savoir qui accepte le code du
prototype de la fonction.
PurL wrote:
soit le prototype d'une fonction :
---
void Fct(long ¶m = 0);
---
Euh, quel compilateur accepte ca ?
C'est pas autorisé par la norme. Une lvalue est requise pour
initialiser une référence, donc ce code est incorrect.
Avec un passage par adresse, et un long* param = 0, ca devient
correct. Mais pas en passage par référence. Par contre dans ce
cas le code de la fonction est à changer, et un test sur NULL
à faire avant de faire toute opération de déréférencement sur
param.
Mais si je fais ça :
Fct();
Quelle référence de variable Fct reçoit-elle ? un temporaire ?
si oui, l'appel à Fct(a) passe-t-il aussi par un temporaire ?
si oui pourquoi ?
L'appel à Fct(a) n'a pas à ma connaissance à passer par un
temporaire, vu que c'est un passage par référence.
Et vu que le code d'origine n'est pas conforme, je ne peux pas
répondre à la première question.
J'ai été surpris de voir que mon compilateur ne bronchait pas
quand j'ai écrit Fct() !
Et moi je serai curieux de savoir qui accepte le code du
prototype de la fonction.
Anthony Fleury wrote:PurL wrote:soit le prototype d'une fonction :
---
void Fct(long ¶m = 0);
---
Euh, quel compilateur accepte ca ?
La plupart.
C'est pas autorisé par la norme. Une lvalue est requise pour
initialiser une référence, donc ce code est incorrect.
Ce n'est pas si évident. Je l'ai vérifié, et c'est bien
interdit, mais si la fonction était l'instanciation d'un
template, il serait tout à fait légal, tant que le programmeur
se servait pas de la valeur par défaut.
Mais si je fais ça :
Fct();
Quelle référence de variable Fct reçoit-elle ? un temporaire ?
si oui, l'appel à Fct(a) passe-t-il aussi par un temporaire ?
si oui pourquoi ?
L'appel à Fct(a) n'a pas à ma connaissance à passer par un
temporaire, vu que c'est un passage par référence.
Sauf que dans son exemple, le paramètre réel n'avait pas le même
type que le paramètre formel. Donc, il y a une conversion, qui
donne un temporaire.
Anthony Fleury wrote:
PurL wrote:
soit le prototype d'une fonction :
---
void Fct(long ¶m = 0);
---
Euh, quel compilateur accepte ca ?
La plupart.
C'est pas autorisé par la norme. Une lvalue est requise pour
initialiser une référence, donc ce code est incorrect.
Ce n'est pas si évident. Je l'ai vérifié, et c'est bien
interdit, mais si la fonction était l'instanciation d'un
template, il serait tout à fait légal, tant que le programmeur
se servait pas de la valeur par défaut.
Mais si je fais ça :
Fct();
Quelle référence de variable Fct reçoit-elle ? un temporaire ?
si oui, l'appel à Fct(a) passe-t-il aussi par un temporaire ?
si oui pourquoi ?
L'appel à Fct(a) n'a pas à ma connaissance à passer par un
temporaire, vu que c'est un passage par référence.
Sauf que dans son exemple, le paramètre réel n'avait pas le même
type que le paramètre formel. Donc, il y a une conversion, qui
donne un temporaire.
Anthony Fleury wrote:PurL wrote:soit le prototype d'une fonction :
---
void Fct(long ¶m = 0);
---
Euh, quel compilateur accepte ca ?
La plupart.
C'est pas autorisé par la norme. Une lvalue est requise pour
initialiser une référence, donc ce code est incorrect.
Ce n'est pas si évident. Je l'ai vérifié, et c'est bien
interdit, mais si la fonction était l'instanciation d'un
template, il serait tout à fait légal, tant que le programmeur
se servait pas de la valeur par défaut.
Mais si je fais ça :
Fct();
Quelle référence de variable Fct reçoit-elle ? un temporaire ?
si oui, l'appel à Fct(a) passe-t-il aussi par un temporaire ?
si oui pourquoi ?
L'appel à Fct(a) n'a pas à ma connaissance à passer par un
temporaire, vu que c'est un passage par référence.
Sauf que dans son exemple, le paramètre réel n'avait pas le même
type que le paramètre formel. Donc, il y a une conversion, qui
donne un temporaire.
Ce n'est pas si évident. Je l'ai vérifié, et c'est bien
interdit, mais si la fonction était l'instanciation d'un
template, il serait tout à fait légal, tant que le
programmeur se servait pas de la valeur par défaut.
En effet, j'ai testé avec Comeau Online, et ceci :
template<class T> void fct(T& p = 0);
template<class T> void fct(T& p) {
}
int main() {
int a;
fct<int>(a);
}
Compile sans problème à ma plus grande surprise.
L'initialisation d'une référence devant toujours être pour moi
une lvalue, je ne vois pas pourquoi ceci compile, même si on
n'instancie pas fct de manière à ce qu'elle utilise la valeur
par défaut.
Vu qu'il est _possible_ d'instancier fct de manière à avoir ce
comportement, ca me parait être une erreur.
Par contre, vu que :
template<class T> void fct(long &p = 0);
template<class T> void fct(long& p) {
}
int main() {
int a;
fct<int>(a);
}
Ne compile pas pour la même raison que le code de départ avec
Comeau online, je me pose une question, y-a-t-il un type en
C++ pour lequel l'initialisation d'une référence à 0 est
valide ?
et donc ce que je dis sur les lvalues serait faux
pour ce type ?
car si il rejette le premier dans le cas d'un paramètre T
inconnu et pas le second, c'est que ca doit être permis pour
un type et donc que ce code *pourrait* être valide quelque
part. Me tromperai-je ?
Ce n'est pas si évident. Je l'ai vérifié, et c'est bien
interdit, mais si la fonction était l'instanciation d'un
template, il serait tout à fait légal, tant que le
programmeur se servait pas de la valeur par défaut.
En effet, j'ai testé avec Comeau Online, et ceci :
template<class T> void fct(T& p = 0);
template<class T> void fct(T& p) {
}
int main() {
int a;
fct<int>(a);
}
Compile sans problème à ma plus grande surprise.
L'initialisation d'une référence devant toujours être pour moi
une lvalue, je ne vois pas pourquoi ceci compile, même si on
n'instancie pas fct de manière à ce qu'elle utilise la valeur
par défaut.
Vu qu'il est _possible_ d'instancier fct de manière à avoir ce
comportement, ca me parait être une erreur.
Par contre, vu que :
template<class T> void fct(long &p = 0);
template<class T> void fct(long& p) {
}
int main() {
int a;
fct<int>(a);
}
Ne compile pas pour la même raison que le code de départ avec
Comeau online, je me pose une question, y-a-t-il un type en
C++ pour lequel l'initialisation d'une référence à 0 est
valide ?
et donc ce que je dis sur les lvalues serait faux
pour ce type ?
car si il rejette le premier dans le cas d'un paramètre T
inconnu et pas le second, c'est que ca doit être permis pour
un type et donc que ce code *pourrait* être valide quelque
part. Me tromperai-je ?
Ce n'est pas si évident. Je l'ai vérifié, et c'est bien
interdit, mais si la fonction était l'instanciation d'un
template, il serait tout à fait légal, tant que le
programmeur se servait pas de la valeur par défaut.
En effet, j'ai testé avec Comeau Online, et ceci :
template<class T> void fct(T& p = 0);
template<class T> void fct(T& p) {
}
int main() {
int a;
fct<int>(a);
}
Compile sans problème à ma plus grande surprise.
L'initialisation d'une référence devant toujours être pour moi
une lvalue, je ne vois pas pourquoi ceci compile, même si on
n'instancie pas fct de manière à ce qu'elle utilise la valeur
par défaut.
Vu qu'il est _possible_ d'instancier fct de manière à avoir ce
comportement, ca me parait être une erreur.
Par contre, vu que :
template<class T> void fct(long &p = 0);
template<class T> void fct(long& p) {
}
int main() {
int a;
fct<int>(a);
}
Ne compile pas pour la même raison que le code de départ avec
Comeau online, je me pose une question, y-a-t-il un type en
C++ pour lequel l'initialisation d'une référence à 0 est
valide ?
et donc ce que je dis sur les lvalues serait faux
pour ce type ?
car si il rejette le premier dans le cas d'un paramètre T
inconnu et pas le second, c'est que ca doit être permis pour
un type et donc que ce code *pourrait* être valide quelque
part. Me tromperai-je ?