Dupliqué possible: strong>
pourrait-on expliquer ces comportements non définis (i = i ++ + ++ i, i = i ++, etc ...) p>xxx pré> Je sais quelle est la sortie du code. p>
as #define travail dans un autre programme De cette façon, cela ne fonctionne pas dans le code ci-dessus Pourquoi? P> BlockQuote>
9 Réponses :
Le résultat d'une expression avec plus d'un opérateur ++ sur la même variable est officiellement un comportement
Est-ce techniquement "comportement non défini"? Je pensais que c'était un «comportement non spécifié», qui est toujours mauvais, mais limite la mise en œuvre à certains choix (dans ce cas, n'incluez pas de crash).
Oui, c'est certainement indéfini;).
Au fait, cette réponse n'est pas exactement correcte. Une expression peut modifier la même variable plusieurs fois - le comportement n'est indéfini que si entre ces modifications Il n'y a pas de point de séquence (I.e. &&, ||, ?:, Opérateur de virgule ou appel de la fonction)
Un avocat de langue Je ne suis pas :) et je ne joue pas non plus à la télévision.
Parce que définir simplement remplace l'expression. Donc, vous obtenez en résultat:
b1 = (a1++)*(a1++); b2 = (++a2)*(++a2;
Vous avez ajouté des parenthèses à l'expansion. Cela ne fait aucune différence dans ce cas, mais cela fait parfois une énorme différence.
@ Darron d'accord avec vous. Pour des raisons de lisibilité ici.
Les deux utilisations de SQ invoquent un comportement non défini, car ils attribuent à A1 et A2 plus d'une fois par point de séquence. Vous ne devez pas passer des expressions avec des effets secondaires tels que des affectations ou des incréments des macros. P>
Enveloppez les opérandes dans la macro entre parenthèses: également, essayez de ne pas fonctionner avec x ++ et x dans la même cession. Pourrait conduire à un comportement indéfini. P> acclamations! P> p>
comme Seva States, ces expressions sont officiellement indéfinies; Mais même si nous prenons ce qui est sans doute la lecture la plus judicieuse, vous obtiendrez toujours #define code> est une instruction au prétraiteur pour remplacer littéralement chaque occurrence de la macro avec son expansion. Donc, les lignes pertinentes de votre code passeront au compilateur comme suit:
b1 = 2 * 3; code> et
b2 = 3 * 4; code> (avec les deux
A1 code> et
A2 code> défini sur 4 après les lignes. p> p>
Regardez le code tel qu'il sera élargi par le préprocesseur:
b1 = a1++ * a1++; b2 = ++a2 * ++a2;
Les lignes développent p> qui invoquent le comportement non défini (un objet peut avoir sa valeur modifiée au plus une fois entre la séquence Points), ce qui signifie tout résultat em> est considéré comme "correct". p> C'est le problème avec ces types de macros; Vous voulez vraiment que l'argument soit évalué une fois em>, mais en raison de l'expansion, elle est évaluée deux fois. p> Il y a aussi le problème de l'appeler avec une expression comme p> < Pré> xxx pré> Ceci va s'étendre à p> ce qui n'est probablement pas ce que vous vouliez. Préserver la préséance de l'opérateur, l'expansion doit être enveloppée dans () code>, telle que p>
Re votre dernier point, vous devez également envelopper l'expression entière entre parenthèses, à savoir #define sq (x) ((x) * (x)) code> sinon expressions comme
x = -sq (4 ) code> pourrait donner des résultats inattendus.
@Jeremyp: Oups, oui, tu as raison. Pouvez-vous dire que je n'utilise pas beaucoup de macros comme ça?
Je ne sais vraiment pas quelle est votre question, mais peut-être que vous avez des problèmes avec votre production attendue ...
Sachez que Si vous regardez ici: Question sur C Programmation Vous pouvez voir des explications comme pourquoi " A ++ * A ++ "est un comportement officiellement indéfini. P> #define code> est un remplacement de texte "simple" qui fonctionne avant que votre code compile.
Ce remplacement de texte n'a aucun respect de la portée ou des correcteurs syntaxiques. Il remplace simplement tout ce qui correspond à ce que vous avez dit.
Dans votre cas, il ne ferait pas vraiment un carré du résultat de "A ++", il serait plutôt
Générez ce code: B1 = A ++ * A ++; P>
Félicitations! Vous venez de découvrir pourquoi il est un mauvaise idée em> utiliser des macros pour ce genre de chose. En règle générale, ne faites que quelque chose une macro si elle ne peut pas être faite à l'aide d'une fonction. Dans ce cas, SQ code> pourrait facilement être implémenté comme fonction à la place:
int sq (int x)
{
return x * x;
}
+1 pour un point plus important que le langage C ++ Arcana
Que se passe-t-il lorsque vous compilez et exécutez cela? Les erreurs? Des résultats étranges? Quoi?
Quelle est la sortie que vous attendez et qu'est-ce que vous obtenez? Je suis à peu près sûr que dans x ++ * x ++ et ++ y * ++ y * * Il est indéfini si le premier incrément est arrivé au moment où le second est évalué, la valeur que vous obtenez variera d'un environnement à l'environnement.
Dans votre question originale, il y avait un typo (
#deifne code> au lieu de
#define code>) J'ai corrigé maintenant, assurez-vous que le code que vous utilisez est correct.