Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Initialisation de variable (!)

23 réponses
Avatar
Aurélien REGAT-BARREL
Hello à tous,
Je ne comprends pas pourquoi dans l'exemple suivant b3 est considéré comme
la déclaration d'un prototype de fonction (VC++ 7.1, MingW 3.3.1), d'autant
plus que b2 est valide.

class A
{
public:
A( int ) {}
};

class B
{
public:
B( A a1, A a2 ) {};
};

int main()
{
int i1 = 0;
int i2 = 0;

A a1( 0 );
A a2( 0 );

B b1( a1, a2 );
B b2( A( 0 ), A( 0 ) );
// warning C4930 : 'B b3(A,A)' : fonction prototypée non appelée
// (était-ce la définition de variable souhaitée ?)
B b3( A( i1 ), A( i2 ) );
}

La suite du programme montre bien que b3 est considéré comme une fonction.
Merci.

--
Aurélien REGAT-BARREL

10 réponses

1 2 3
Avatar
Julien Lamy
Aurélien REGAT-BARREL wrote:
Hello à tous,
Je ne comprends pas pourquoi dans l'exemple suivant b3 est considéré comme
la déclaration d'un prototype de fonction (VC++ 7.1, MingW 3.3.1), d'autant
plus que b2 est valide.


[...]

La suite du programme montre bien que b3 est considéré comme une fonction.
Merci.



Bug des compilateurs ? g++ 3.3.4 et 3.4.2 compilent sans problème.
--
Julien Lamy

Avatar
Arnaud Meurgues
Aurélien REGAT-BARREL wrote:

Je ne comprends pas pourquoi dans l'exemple suivant b3 est considéré comme
la déclaration d'un prototype de fonction (VC++ 7.1, MingW 3.3.1), d'autant
plus que b2 est valide.


1 > B b2( A( 0 ), A( 0 ) );
// warning C4930 : 'B b3(A,A)' : fonction prototypée non appelée
// (était-ce la définition de variable souhaitée ?)
2 > B b3( A( i1 ), A( i2 ) );


C'est un problème classique du C++.

En fait, le compilateur lit la ligne 2 ainsi :

B b3(A (i1), A (i2));

C'est-à-dire qu'il voit le prototype d'une fonction b3 renvoyant B et
prenant deux arguments, i1 et i2, tous deux de type A.

La ligne 1 ne génère pas la même ambiguïté, puisque 0 ne peut pas être
pris pour un nom de variable.

Le contournement est de parenthéser chaque argument :

B b3((A(i1)), (A(i2)));

La grammaire ne permettant pas que des arguments de fonctions soient
décrit entre parenthèses, celà lève l'ambiguïté.

--
Arnaud
(Supprimez les geneurs pour me répondre)

Avatar
Aurélien REGAT-BARREL
Bug des compilateurs ? g++ 3.3.4 et 3.4.2 compilent sans problème.
Seul VC++ me met l'avertissement.

Ajoute un test
if ( b1 == b3 );
et recompile...

--
Aurélien REGAT-BARREL

Avatar
Aurélien REGAT-BARREL
C'est un problème classique du C++.

En fait, le compilateur lit la ligne 2 ainsi :

B b3(A (i1), A (i2));

C'est-à-dire qu'il voit le prototype d'une fonction b3 renvoyant B et
prenant deux arguments, i1 et i2, tous deux de type A.

La ligne 1 ne génère pas la même ambiguïté, puisque 0 ne peut pas être
pris pour un nom de variable.

Le contournement est de parenthéser chaque argument :

B b3((A(i1)), (A(i2)));

La grammaire ne permettant pas que des arguments de fonctions soient
décrit entre parenthèses, celà lève l'ambiguïté.


Ah... Effectivement ça corrige. Pfff, 2 heures là dessus.
Merci.

--
Aurélien REGAT-BARREL

Avatar
Fabien LE LEZ
On Wed, 24 Nov 2004 15:38:49 +0100, Arnaud Meurgues
:

C'est-à-dire qu'il voit le prototype d'une fonction b3 renvoyant B et
prenant deux arguments, i1 et i2, tous deux de type A.


Plus exactement, il y a deux interprétations possibles : une
déclaration de fonction et une déclaration de variable. Et dans pareil
cas, l'interprétation "déclaration de fonction" est toujours
privilégiée.


--
;-)

Avatar
kanze
Fabien LE LEZ wrote in message
news:...

On Wed, 24 Nov 2004 15:38:49 +0100, Arnaud Meurgues
:

C'est-à-dire qu'il voit le prototype d'une fonction b3 renvoyant B et
prenant deux arguments, i1 et i2, tous deux de type A.


Plus exactement, il y a deux interprétations possibles : une
déclaration de fonction et une déclaration de variable. Et dans pareil
cas, l'interprétation "déclaration de fonction" est toujours
privilégiée.


Non. L'abiguïté se situe plus bas, avec la suite de tokens « A(i1) ».
C'est là où il y a deux interprétations possibles : c'est une expression
(une « Explicit type conversion (functional notation) », §5.2.3), ou
c'est la déclaration d'une variable. Les deux sont légale dans ce
contexte, et la règle, c'est qu'en cas d'ambiguïté, on privilège la
déclaration plutôt que l'expression.

Évidemment, une fois qu'on a décidé qu'il s'agit des declarations, il
n'y a plus d'ambiguïté entre une declaration de fonction ou une
declaration d'une variable.

Note que selon la norme, il suffit qu'il y a un seul « paramètre » qui
ne peut pas être une declaration pour que l'interprêtation fonction ne
soit pas possible, et que donc, on se trouve dans un contexte où une
declaration ne serait pas légale pour les autres paramètres. Ce qui
n'est pas ce qu'il y a de plus simple pour un compilateur, et certains
ont eu (et peut-être ont encore) des problèmes avec ça. Du coup, il est
préférable de désambiguër tous les paramètres.

--
James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Gabriel Dos Reis
writes:

| Note que selon la norme, il suffit qu'il y a un seul « paramètre » qui
| ne peut pas être une declaration pour que l'interprêtation fonction ne
| soit pas possible, et que donc, on se trouve dans un contexte où une
| declaration ne serait pas légale pour les autres paramètres. Ce qui
| n'est pas ce qu'il y a de plus simple pour un compilateur, et certains
| ont eu (et peut-être ont encore) des problèmes avec ça. Du coup, il est
| préférable de désambiguër tous les paramètres.

Cela doit être simple, parce que certains proposent d'ajouter des
« contextual keywords » -- certains langages récents avec la syntaxe
de C++ l'ont fait.

:-(

-- Gaby
Avatar
drkm
Gabriel Dos Reis writes:

Cela doit être simple, parce que certains proposent d'ajouter des
« contextual keywords » -- certains langages récents avec la syntaxe
de C++ l'ont fait.


Tu penses à des propositions particulières ? Lesquelles ? Et à
quelles constructions penses-tu dans d'autres langages ? Par simple
curiosité.

--drkm

Avatar
Gabriel Dos Reis
Fabien LE LEZ writes:

| On Fri, 26 Nov 2004 00:10:12 +0100, Loïc Joly
| :
|
| >Extrait du MSDN :
| >> A contextual keyword is used to provide a specific
| >> meaning in the code, but it is not a reserved word in C#.
|
| Euh... déjà ça, je le sens mal. Si je comprends bien, "yield", par
| exemple, peut avoir un sens précis pour le compilo à certains
| endroits, et être un simple identifiant à d'autres ? °_°

Oui.

http://blogs.msdn.com/hsutter/archive/2003/11/23/53519.aspx

-- Gaby
Avatar
Fabien LE LEZ
On 26 Nov 2004 03:35:52 +0100, Gabriel Dos Reis
:

http://blogs.msdn.com/hsutter/archive/2003/11/23/53519.aspx


Pourquoi faire simple quand on peut faire compliqué...
Z'ont même pas été fichus de pondre des mots-clés commençant
par "__" -- c'est pourtant une technique assez classique pour
définir des mots-clefs spéfiques à un compilo et/ou un système.


--
;-)

1 2 3