12
votes

Pourquoi n'y a-t-il pas || = opérateur en C / C ++?

Duplicates possibles: strong>

&& = et || = opérateurs p>

Voir le titre. Cette question peut être élargie pour inclure tous les opérateurs d'affectation logique +. Pour clarifier: Je ne parle pas de | = Opérateur. P>

Un autre exemple: && = P>

Merci. P>

Exemple: P>

bool result = false;

// Today
result = result || my_test1();
// Do stuff
result = result || my_test2();

// In my imagination only...
result ||= my_test1();
// Do stuff
result ||= my_test2();


6 commentaires

Quel serait exactement l'affaire d'utilisation pour un tel opérateur?


Il y a des opérateurs pour une construction aussi (rarement, si jamais, nécessaire). La syntaxe est | = !! et & = = , respectivement. Que ce soit du code que vous souhaitez écrire est une question différente (bien que, avec certes, j'ai utilisé au moins le !! idiome quelques fois avant, et le probable macro dans le Les sources de noyau Linux l'utilisent également).


@Damon: | = !! n'est pas un opérateur, c'est une combinaison de trois opérateurs: | =! ! et la haute précision du ! conduit à des problèmes si vous avez une expression avec une prime inférieure, comme + sur le côté droit, e. g. x | = !! 5 + x vous donnera x | = 1 + x .


@drhirsch: Oui, je suis bien conscient que ce n'est pas un seul opérateur, bien que la combinaison des opérateurs fait quelle question la question (avant la modification) a demandé dans une interprétation possible. Comme je l'ai écrit ci-dessus, ce n'est pas quelque chose que l'on voudrait probablement utiliser (mais pas tant à cause de problèmes de priorité, mais plutôt parce qu'il peut ne pas être immédiatement évident à sonner à sonner ce qui est destiné). C'est un peu comme le style dans le "Rangecoder russe" plutôt connu.


@Damon, il n'aura pas non plus l'évaluation paresseuse du || opérateur, qui est assez important.


@Suma: Votre duplicata potentiel concerne Java PAS C.


4 Réponses :


15
votes

À une conjecture, car ils ne feraient aucun sens pour les bools, qui étaient en retard à la fête

Même si les bools avaient été autour au début, ces opérateurs seraient d'une utilisation limitée, car sans effets secondaires, ils seraient identiques à | = et & = avec Opérandes booléens, la seule utilisation serait piéger en passant un non-bool par accident.

Si les opérateurs proposés sont également à court-circuit (pas déraisonnable comme || et && sont destinés à des types intégrés), vous avez également une justification supplémentaire pour eux en présence d'effets secondaires.

La seule autre raison possible que je puisse penser à leur permettre de les laisser si elle simplifiait considérablement l'analyse / la compilation de la langue, cependant, ce n'est probablement pas le cas étant donné qu'ils n'ont pas de sens pour les types non-Bool.

En fin de compte, ils ne sont pas dans la langue, car personne n'a été suffisamment soigné pour les mettre dans la langue, nous pouvons donc conclure qu'aucune de ces justifications ne suffit pour justifier le coût de la soumission d'une proposition, l'obtenir dans la norme et la mise en œuvre la fonctionnalité.


6 commentaires

"Comme ils seraient identiques à | = et & =" non, ils ne seraient pas les mêmes. bool a = vrai; a || = somecomplexfuncreturningboolfteranhour ()


"La seule utilisation serait piéger à la réussite d'un non-bool par accident" ... cela implique que l'utilisation n'est pas suffisante de justification, mais je suis suffisant. En outre, vous avez manqué le fait que && et || sont des opérations de court-circuit et si la langue fournit un court-circuit || = = = et && = ils seraient potentiellement plus efficaces - et utilisables malgré des problèmes potentiels-pointer-pointeur, etc. - que absorber | = et & = pour le même code.


Aurait suscité, si la réponse était composée de la première phrase seulement. && = fait le plus de sens que && : 3 && 4 est vrai, tandis que 3 et 4 est faux.


-1 || = ne serait pas équivalent à | = . Le résultat de || est uniquement 1 ou 0 (C99 6.5.14).


@Jeremyp donc admissible pour les opérandes booléens


@JK: Il est toujours légal d'utiliser && et || Pour les opérandes entier et attribuez le résultat à un entier. int A = 27; A = A && B; est légal. Donc a && = b; serait théoriquement légal si l'opérateur existait.



8
votes

Parce qu'ils n'auraient pas de sens. La définition de x op = y est x = x op y y , sauf que x n'est évalué qu'une seule fois. Qu'est-ce que cela signifie avec un opérateur court-circuité, qui convertit chacun de ses opérandes (s'il les évalue) à BOOL ? L'équivalent de || = pourrait être quelque chose comme: xxx

qui est certainement différent de l'interprétation d'un autre op = .


8 commentaires

Vous avez pratiquement contré votre déclaration liminaire! :-) Le fonctionnement de courte-circuits de construction est une observation aiguë et votre équivalent proposé me donne des sens pour les types intégrés. Conformément au comportement C ++ pour les types définis par l'utilisateur, vous vous attendez à ce que vous attendez explicitement défini par l'utilisateur opérateur && = (bool rhs) ne pas être court-circuit. C'est toute une smidge bizarre, mais est en accord avec ce que C ++ fait maintenant ... s'il était proposé pour une future norme C ++, je ne peux imaginer que personne s'oppose sérieusement à ce qu'il "n'aurait pas de sens".


@Tony le propose, alors. Ma déclaration liminaire peut avoir été trop générale: op = Les opérateurs ne peuvent pas avoir le même sens que conventionnel op = opérateurs; La définition pour eux devrait être différente si nous voulons maintenir le court-circuit. (D'autre part, l'utilisateur défini || et && ne pas court-circuit, il y a donc un précédent pour le laisser tomber. Mauvais précédent, IMHO.)


Mon raisonnement (peu importe si x est évalué une fois si possible ou non) serait que puisque "A = A && B" est parfaitement pensable et utilisable, puis "A && = B" pourrait être donné aussi ; Ainsi, je pense que c'est juste parce qu'ils sont "en retard" comme un autre utilisateur a répondu.


@James: "mauvais précédent" ... qui suggère peut-être une proposition plus intéressante et plus radicale ... que les classes puissent définir une fonction par exemple. bool opérateur && () const / bool opérateur || () const qui indique si elles doivent s'ils devraient être court-circuit: le compilateur pourrait organiser un appel à cela avant d'évaluer l'argument pour < Code> bool opérateur && (... rhs) const . Semble aussi compatible en arrière.


@Shin Takzou ils ne sont pas en retard; || et && existe depuis les premiers jours de C. La raison (je suis presque sûr) est parce que op = est défini comme x = x op y y , et cette définition ne fait pas trop de sens pour les opérateurs à court-circuit.


Je ne suis pas d'accord avec "n'aurait pas de sens", mais c'est ma réponse préférée dans l'ensemble. C n'a pas d'affectation à court-circuit, et s'ils existaient, ils seraient essentiellement sténographiques "cachés" des conditionnels, beaucoup plus faciles à ne pas remarquer que d'un explicite si . Vous pouvez faire des arguments similaires pour && etc., mais peut-être qu'il y a un cas plus fort pour l'utilité / la commodité dépassant la bizarrerie.


Je voudrais une construction comme "A || = B" où un séjour est vrai et B sera ignoré quand A est vrai, sinon une valeur booléenne de B (et B évaluée) et "similaire" pour a && = b. Je ne vois aucune raison de ne pas permettre cela (ou de rester de côté, je pourrais dire que je ne vois aucune raison d'avoir OP =, ou même - ++)


@Shintakezou je comprends ce que tu veux. À mon avis, ce n'est pas déraisonnable; En tout cas, il est plus raisonnable que de pouvoir surcharger && et || . Mais cela signifie défini pour définir une autre sémantique pour le op = que pour les autres, et personne n'a jamais apporté une proposition (à ma connaissance, au moins) dans cette direction.



5
votes

Pas de bonne raison logique ... juste des pressions historiques pour les fonctionnalités.

Les opérateurs logiques ne sont normalement pas disponibles comme opcodes de processeur unique, de sorte qu'ils ne sont pas aussi bon marché ou fondamentaux comme des homologues bitwises. Un Xor logique serait bien aussi, peut-être ^^ , puis ^^ = . .

Néanmoins, une prolifération des opérateurs rend de plus en plus pénible de créer des types déposés par l'utilisateur avec une sémantique de style intégré, et il y a peu de gain du monde réel. J'aimerais toujours les voir - ces opérateurs existent dans d'autres langues, comme Ruby, et je les ai trouvées pratiques et expressives.


3 commentaires

+1 La "non bonne raison logique ..." me semble l'explication la plus logique, bien que le suivi des opcodes de la CPU ne me convainc pas totalement (les processeurs peuvent avoir une "définition sur la condition" et des opérateurs bitwises sur des entiers qui sont juste 1 ou 0 se comporter comme des opérateurs logiques)


@Shintakezou: "Définir la condition" peut faciliter la cartographie des entiers à Booleans, mais si vous avez deux registres ou un emplacement de mémoire avec des entiers et que vous devez d'abord "tester" pour définir les conditions, utilisez cette condition pour générer une "norme" 0 Versus 1 Valeur booléenne, puis appliquez l'opérateur bitwise - vous avez plus de pas. Quelque chose d'appartienne à ou Rega, Rega // définit les conditions; SET0IFZ_1IFNZZ REGA; Avant de pouvoir effectuer une opération bitwise. Le "SET0IFZ_1IFNZ" pourrait ne pas être disponible comme un seul opcode non plus.


Je suis d'accord, mais je suppose également que ces "limites" des CPU ne peuvent pas affecter la syntaxe des langues modernes de nos jours, si on ne voyait pas utile d'avoir une telle syntaxe, bien sûr; Les compilateurs peuvent ensuite optimiser fortement le code produit, quelle que soit la source de la source (par ex. A ++ "de C contre" A = A + 1 "d'autres langues peut produire le même code)



3
votes

Parce que leur modus operandi est largement différent.

Regardez les signatures: P>

T operator+(T,T);
T& T::operator+=(T);

T operator*(T,T);
T& T::operator*=(T);

bool operator&&(T,T);
???


5 commentaires

Je n'ai jamais essayé cela, mais je suppose que "Floata & FloaBeb" n'a pas beaucoup de sens, bien que le résultat puisse être, formellement, un flotteur; De plus en particulier en C où il n'y a pas de type de bool primitif et que nous pouvons utiliser un int pour cela; Donc, si "Doublea & = Floathb" est possible, même "A && = B" devrait être, je pense.


" &&, || et ^ Les opérateurs renvoient un booléen" ... Nope, ^ est un opérateur bitwise, que ce n'est pas universellement connu pourrait être parce qu'ils peuvent être appliqué aux booléens avec un certain succès, bien que ce soit risqué. En outre, cela suppose que vous parlez de surcharge de C ++, mais ne discutez pas pourquoi les compilateurs C et C ++ ne fournissent pas ces opérations pour des booléens intégrés.


@Shintakezou: Il n'y a pas bool mais à propos de tout le monde a un bool typéfed et il y a une notion de contexte booléen pour les conditions @tony: Droite pour ^ < / code>, j'ai glissé. Je ne parlais pas (pas vraiment) sur la surcharge de l'opérateur, j'ai juste besoin d'exposer les signatures pour montrer la différence.


@Matthieu && @shin: C99 a maintenant un type primitif booléen.


En fait, je suis habitué à inclure stdbool.h et utilisez Bool comme type primitif; Formellement, je m'attends à ce que "T && A" entraînait un bool où le contexte booléen est donné par le && lui-même. En C, "A = A && B" où A et B sont tous les deux int, c'est d'accord. Donc, je voulais dire, nous n'avons pas besoin de la contrainte "booléenne seulement".