Opérateur ternaire conditionnel et d'assignation priorité
je suis confus au sujet de l'assignation directe et des opérateurs conditionnels ternaires priorité:
#include<stdio.h>
int main(void)
{
int j, k;
j = k = 0;
(1 ? j : k) = 1; // first
printf("%d %dn", j, k);
j = k = 0;
1 ? j : k = 1; // second
printf("%d %dn", j, k);
return 0;
}
j'attendrais la sortie:
1 0
1 0
Mais il se trouve être:
1 0
0 0
en Plus je obtenir cette mise en garde:
main.rpc:20: avertissement: l'instruction n'a pas d'effet
ce qui est à propos de la ligne que j'ai commentée en second.
puisque l'opérateur d'assignation directe a moins de préséance que le ternaire opérateur conditionnel, Je m'attendais à ce que les lignes commentées en premier et deuxième soient équivalentes. Mais hélas ce n'est pas le cas.
j'ai essayé avec g++ -- version (Ubuntu 4.4.3-4ubuntu5) 4.4.3
4 réponses
l'opérateur de préséance dans le langage C / C++ n'est pas défini par une table ou des nombres, mais par une grammaire. Voici la grammaire pour opérateur conditionnel de C++0x projet chapitre 5.16 opérateur Conditionnel [expr.cond]:
conditional-expression: logical-or-expression logical-or-expression ? expression : assignment-expression
la table de priorité comme celui-ci est donc correct lorsque vous utilisez assignment sur le côté gauche du doublecolon, mais pas lorsqu'il est utilisé sur le côté droit. Quelle est la raison de cette asymétrie je n'ai pas de idée. C'est peut-être une raison historique: en C, le résultat conditionnel n'était pas de la valeur de L, donc lui attribuer quelque chose n'avait pas de sens, et permettre à l'attribution d'être acceptée sans parenthèses pouvait sembler intelligent à ce moment-là.
La deuxième ligne est équivalent à:
1 ? (j) : (k = 1);
C'est la même chose que:
j;
C'est la même chose que:
;
La clé est que les deux opérandes de l'opérateur conditionnel ternaire peut être expressions, donc la préséance de l'opérateur n'est pas pertinente ici. C'est simplement que le second opérande est l'expression assignment k = 1
.
(1 ? j : k) = 1;
est équivalent à
if(true) j = 1;
else k = 1;
Et
1 ? j : k = 1;
est équivalent à
if(true) j; // warning: statement has no effect
else k = 1;
dans le second cas,
1 ? j : k = 1;
est évalué comme:
(1) ? (j) : (k = 1);
et puisqu'on évalue à true
, l'expression j
qui ne fait rien.