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

31
demandé sur Ari Brodsky 2011-09-21 16:02:21

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à.

19
répondu Suma 2013-08-08 15:01:29

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.

14
répondu Kerrek SB 2011-09-21 12:11:35
(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;
9
répondu iammilind 2011-09-21 12:09:31

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.

4
répondu quasiverse 2011-09-21 12:07:31