OVH Cloud OVH Cloud

int x= x+1

66 réponses
Avatar
Fabien LE LEZ
Bonjour,

Il me semble que l'expression suivante est autorisée (même si elle a
un comportement indéfini) :

int x= x+1;

Y a-t-il une raison pour laquelle les auteurs de la norme n'ont pas
purement et simplement interdit cette écriture ? Accessoirement, y
a-t-il des cas (pas trop tordus) où elle peut être utile ?

Merci d'avance...

10 réponses

1 2 3 4 5
Avatar
Marc Boyer
Matthieu Moy a écrit :
Marc Boyer writes:

Ben, propose un ammendement à la norme si tu trouves ça
simple à exprimer, à comprendre et à implémenter.


Encore une fois, c'est comme ça que c'est fait dans de nombreux
langages. Ma proposition n'a rien d'un scoop, hein...


Oui, mais est-ce une restriction utile ? Et surtout,
avec le pb de compatibilité ascendante du C, est-ce
ce que cela casserait du code ?

Mais bon, je te refais l'exemple en variable locale:
int x=f(x);
est-ce une contruction à prohiber ? Je n'en sais rien.


Si tu considère que la déclaration n'est effective qu'à la fin de
l'instruction, le f(x) est refusé, car x n'est pas encore déclaré à ce
moment là. Je ne vois d'ailleurs pas en quoi la fonction « f » est si
différente que la fonction « + », hormis la syntaxe.


Le code de f peut ignorer la valeur de x:
int f(int &i){
static bool first= true;
if (first){
first= false;
return 0;
} else {
i++;
return i;
}
}

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?


Avatar
Matthieu Moy
Marc Boyer writes:

Matthieu Moy a écrit :
Marc Boyer writes:

Ben, propose un ammendement à la norme si tu trouves ça
simple à exprimer, à comprendre et à implémenter.


Encore une fois, c'est comme ça que c'est fait dans de nombreux
langages. Ma proposition n'a rien d'un scoop, hein...


Oui, mais est-ce une restriction utile ?


Je te retourne la question : est-ce utile d'autoriser cette
construction ? Dans l'implémentation, ça ne complique pas les choses
de l'interdire (dans ta grammaire attribuée, il suffit de passer
l'environnement original à la dernière partie de ta règle. Dans
l'implémentation, il suffit de ne mettre à jour ton environnement
qu'après le traitement de la déclaration). Par contre, ça complique
vraiment de mettre un warning à la place d'une erreur, parce que
pendant le traitement de « x + 1 », le compilateur doit maintenir
l'information « x est déclaré, mais si on l'utilise, je dois mettre un
warning ».

Bref, l'implémentation d'un compilateur décent (qui met des warnings
aux bons endroits) est plus compliqué avec la règle la moins utile
pour le programmeur, mais c'est quand même celle-là qui a été choisie.

Et surtout, avec le pb de compatibilité ascendante du C, est-ce ce
que cela casserait du code ?


Bien sur que la décision aurait du être prise à la création du
langage, pas maintenant. C'est une connerie qui a été faite il y a pas
mal d'année, on peut difficilement la réparer maintenant sans faire
pire que le mal.

Mais bon, je te refais l'exemple en variable locale:
int x=f(x);
est-ce une contruction à prohiber ? Je n'en sais rien.


Si tu considère que la déclaration n'est effective qu'à la fin de
l'instruction, le f(x) est refusé, car x n'est pas encore déclaré à ce
moment là. Je ne vois d'ailleurs pas en quoi la fonction « f » est si
différente que la fonction « + », hormis la syntaxe.


Le code de f peut ignorer la valeur de x:
int f(int &i){
static bool first= true;
if (first){
first= false;
return 0;
} else {
i++;
return i;
}
}


Je peux aussi écrire « int x = x + (- x); ». Mon opérateur « + » n'a
pas besoin de la valeur de x non plus. Mais est-ce utile ?

Tant qu'on y est, pourquoi a-t-on choisi d'interdire

int x = f(y);
int y;

?

Ca pourrait être utile si f ignore la valeur de y, non ?

--
Matthieu



Avatar
Jean-Marc Bourguet
Matthieu Moy writes:

Marc Boyer writes:

Matthieu Moy a écrit :
Marc Boyer writes:

Ben, propose un ammendement à la norme si tu trouves ça
simple à exprimer, à comprendre et à implémenter.


Encore une fois, c'est comme ça que c'est fait dans de nombreux
langages. Ma proposition n'a rien d'un scoop, hein...


Oui, mais est-ce une restriction utile ?


Je te retourne la question : est-ce utile d'autoriser cette
construction ?


Je parie qu'on peut trouver une utilisation legitime, du moins si on
prend l'adresse de la variable plutot que sa valeur (qui non
initialisee pourrait trapper). C'est proche de l'utilisation de this
dans la liste d'initialisation, chose que j'ai deja faite.
Naturellement, il y a des moyens de faire la meme chose autrement.

[...]
Tant qu'on y est, pourquoi a-t-on choisi d'interdire

int x = f(y);
int y;


C'est beaucoup plus complique dans l'optique d'une analyse en une
passe (mais il faut faire ce genre de chose pour les membres de
classes)

(Mais je me demande toujours si sur ce genre de chose, ce n'est pas ce
qui se passait par hasard avec le premier compilateur qui a fini
normalise.)

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org




Avatar
Marc Boyer
Matthieu Moy a écrit :
Marc Boyer writes:
Matthieu Moy a écrit :
Marc Boyer writes:

Ben, propose un ammendement à la norme si tu trouves ça
simple à exprimer, à comprendre et à implémenter.


Encore une fois, c'est comme ça que c'est fait dans de nombreux
langages. Ma proposition n'a rien d'un scoop, hein...


Oui, mais est-ce une restriction utile ?


Je te retourne la question : est-ce utile d'autoriser cette
construction ?


Deux points de vue opposés: doit-on interdire ce qu'on sait
abérant ou ne permettre que ce qui semble raisonnable ?
Je pense que C a choisit de faire confiance au programmeur.
Ensuite, vient la compatibilité C/C++.

Dans l'implémentation, ça ne complique pas les choses
de l'interdire (dans ta grammaire attribuée, il suffit de passer
l'environnement original à la dernière partie de ta règle. Dans
l'implémentation, il suffit de ne mettre à jour ton environnement
qu'après le traitement de la déclaration). Par contre, ça complique
vraiment de mettre un warning à la place d'une erreur, parce que
pendant le traitement de « x + 1 », le compilateur doit maintenir
l'information « x est déclaré, mais si on l'utilise, je dois mettre un
warning ».


OK

que cela casserait du code ?


Bien sur que la décision aurait du être prise à la création du
langage, pas maintenant. C'est une connerie qui a été faite il y a pas
mal d'année, on peut difficilement la réparer maintenant sans faire
pire que le mal.


Je ne sais pas.

Mais bon, je te refais l'exemple en variable locale:
int x=f(x);
est-ce une contruction à prohiber ? Je n'en sais rien.


Si tu considère que la déclaration n'est effective qu'à la fin de
l'instruction, le f(x) est refusé, car x n'est pas encore déclaré à ce
moment là. Je ne vois d'ailleurs pas en quoi la fonction « f » est si
différente que la fonction « + », hormis la syntaxe.


Le code de f peut ignorer la valeur de x:
int f(int &i){
static bool first= true;
if (first){
first= false;
return 0;
} else {
i++;
return i;
}
}


Je peux aussi écrire « int x = x + (- x); ». Mon opérateur « + » n'a
pas besoin de la valeur de x non plus. Mais est-ce utile ?


Dans cet exemple là, clairement non.
Après, dans le cas général, peut-il etre utile d'utiliser une
construction de la forme
int x= f(x);
ma réponse est 'je ne sais pas'.

Tant qu'on y est, pourquoi a-t-on choisi d'interdire

int x = f(y);
int y;

?

Ca pourrait être utile si f ignore la valeur de y, non ?


Parce qu'on ne connait pas son type, et qu'on est incapable
de savoir quelle fonction appeller ?

Marc Boyer
--
À vélo, prendre une rue à contre-sens est moins dangeureux
que prendre un boulevard dans le sens légal. À qui la faute ?




Avatar
Matthieu Moy
Marc Boyer writes:

Après, dans le cas général, peut-il etre utile d'utiliser une
construction de la forme
int x= f(x);
ma réponse est 'je ne sais pas'.


Vu le nombre d'utilisations potentielles (je ne me souviens pas avoir
jamais eu besoin de ça, même si ma carrière de programmeur n'est
encore pas très longue), et la difficulté de contourner (ecrire « int
x; x = f(x); »), si c'était moi qui devais choisir, je n'hésiterais
pas longtemps.

Tant qu'on y est, pourquoi a-t-on choisi d'interdire

int x = f(y);
int y;

?

Ca pourrait être utile si f ignore la valeur de y, non ?


Parce qu'on ne connait pas son type, et qu'on est incapable
de savoir quelle fonction appeller ?


Tu peux très bien considérer que tu traites d'abord les déclarations
de type et ensuite les initialisations, et que ton code est équivalent
à

int x;
int y;
x = f(y);

Ça serait sans doute très bête, mais pas beaucoup plus que « int x x + 1; ».

--
Matthieu


Avatar
JBB
Fabien LE LEZ wrote:
Bonjour,

Il me semble que l'expression suivante est autorisée (même si elle a
un comportement indéfini) :

int x= x+1;

Pour moi ça devrait donner le même résultat que:

int x;
x = x + 1;

Par contre je ne vois pas trop l'intérêt de faire ça.

A la limite: int x = x * 2;
pourrait garantir que x est pair.


Y a-t-il une raison pour laquelle les auteurs de la norme n'ont pas
purement et simplement interdit cette écriture ? Accessoirement, y
a-t-il des cas (pas trop tordus) où elle peut être utile ?

Merci d'avance...



Avatar
Gabriel Dos Reis
Fabien LE LEZ writes:

| Bonjour,
|
| Il me semble que l'expression suivante est autorisée (même si elle a
| un comportement indéfini) :
|
| int x= x+1;

Cela est interdit dans C+03 (ou en tout cas, il y a une formulation
récente pour l'interdire).

|
| Y a-t-il une raison pour laquelle les auteurs de la norme n'ont pas
| purement et simplement interdit cette écriture ? Accessoirement, y
| a-t-il des cas (pas trop tordus) où elle peut être utile ?

Veux-tu banir ceci aussi ?

struct circular_buffer {
circular_buffer* next;
circular_buffer(circular_buffer& c) : next(&c) { }
// ...
};

circular_buffer buffer = buffer;

-- Gaby
Avatar
Gabriel Dos Reis
Matthieu Moy writes:

| Marc Boyer writes:
|
| > Fabien LE LEZ a écrit :
| >> Il me semble que l'expression suivante est autorisée (même si elle a
| >> un comportement indéfini) :
| >>
| >> int x= x+1;
| >>
| >> Y a-t-il une raison pour laquelle les auteurs de la norme n'ont pas
| >> purement et simplement interdit cette écriture ?
| >
| > Peut être parce que le cas général est trop compliqué
| > (voir indécidable):
|
| Oui, enfin, il y a pas mal de langages (y compris si mes souvenirs
| sont bons celui pour lequel j'ai écrit un compilateur en un mois en
| deuxième année d'école d'ingé,

Et c'est un compilateur pour un langage largement utilisé dans la
programmation système, je suppose.

-- Gaby
Avatar
Gabriel Dos Reis
Matthieu Moy writes:

| "Stan" writes:
|
| > Oui, et alors, dans le cas mentionné, ça se traduit comment ?
|
| Pour « int x = x + 1; », le « x » n'est pas encore déclaré quand tu
| parses « x + 1 »,

ce langage ne m'interesse pas alors ; et je suis d'accord que la
solution au problème est hyper simple qu'on ignore le problème.

-- Gaby
Avatar
Gabriel Dos Reis
Matthieu Moy writes:

| Marc Boyer writes:
|
| > Ben, propose un ammendement à la norme si tu trouves ça
| > simple à exprimer, à comprendre et à implémenter.
|
| Encore une fois, c'est comme ça que c'est fait dans de nombreux
| langages.

Nombreux langages ? Quels rapports ont-ils avec C++ ?

-- Gaby
1 2 3 4 5