Question

Que fait le code suivant en C / C ++?

if (blah(), 5) {
    //do something
}
Était-ce utile?

La solution

Un opérateur de virgule est appliqué et la valeur 5 est utilisée pour déterminer le vrai / faux de la condition.

Il va exécuter blah () et obtenir quelque chose en retour (vraisemblablement), puis l'opérateur virgule est employé et 5 sera la seule chose utilisée pour déterminer la valeur vraie / fausse de l'expression.

Notez que l'opérateur, peut être surchargé pour le type de retour de la fonction blah () (qui n'a pas été spécifié), rendant le résultat non évident.

Autres conseils

Si l'opérateur de virgule n'est pas surchargé, le code ressemble à ceci:

blah();
if (5) {
  // do something
}

Si l'opérateur de virgule est surchargé, le résultat sera basé sur cette fonction.

#include <iostream>
#include <string>

using namespace std;

string blah()
{
    return "blah";
}

bool operator,(const string& key, const int& val) {
    return false;
}

int main (int argc, char * const argv[]) {

    if (blah(), 5) {
        cout << "if block";
    } else {
        cout << "else block";
    }

    return 0;
}

(modifié pour afficher le scénario de surcharge par des virgules. Merci à David Pierre pour ses commentaires)

Je sais une chose que ce genre de code devrait faire: il devrait faire virer le codeur. J'aurais un peu peur de travailler à côté de quelqu'un qui écrit comme ça.

Dans le cas pathologique, cela dépend de ce que fait l'opérateur virgule ...

class PlaceHolder
{
};

PlaceHolder Blah() { return PlaceHolder(); }

bool operator,(PlaceHolder, int) { return false; }

if (Blah(), 5)
{
    cout << "This will never run.";
}

Je dirais que cela dépend de blah ().

Sur une réponse plus large. L'opérateur avec virgule (non surchargé) se résout comme dans, exécute la première partie et renvoie la deuxième partie.

Donc si vous avez (foo (), bar ()), les deux fonctions seront exécutées, mais la valeur de l'expression sera évaluée à bar () (ainsi que le type de l'expression).

Bien que je ne dis pas qu'il existe des usages justes à cet égard, cela est généralement considéré comme un peu difficile à lire. Principalement parce que peu de langues partagent de telles constructions. Donc, en règle générale, je l’évite à moins d’ajouter du code à une expression préexistante et de ne pas vouloir changer complètement son format.

Exemple: j'ai une macro (je ne demande pas si vous devez utiliser des macros ou non, parfois ce n'est même pas vous qui l'avez écrite)

FIND_SOMETHING (X) (x> 2)? find_fruits (x): find_houses (x)

Et je l'utilise habituellement dans des tâches telles que my_possession = FIND_SOMETHING (34);

Je souhaite maintenant y ajouter un journal à des fins de débogage, mais je ne peux pas modifier les fonctions de recherche. Je pourrais faire:

FIND_SOMETHING (X) (x> 2)? (LOG ("à la recherche de fruits"), find_fruits (x)) :( LOG ("à la recherche de maisons"), find_houses (x))

J'utilise parfois des constructions comme celle-ci à des fins de débogage. Lorsque je force le si près d'être vrai quelle que soit la valeur de retour de blah. Il est évident qu’il ne devrait jamais figurer dans le code de production.

Ce qui suit a été écrit en supposant qu'il s'agisse de code C, soit dans un fichier C, soit dans un bloc C d'un fichier C ++:

C’est un inutile si . Il appellera blah (), mais le résultat de blah () n’est pas pris en compte par si . La seule chose à prendre en compte est 5, donc le if sera toujours considéré comme vrai. IOW vous pouvez écrire ce code comme

blah();
// do something

sans si du tout.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top