IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Inclure une condition dans un define


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 56
    Par défaut Inclure une condition dans un define
    Salut est il possible de modifier un define en fonction de son paramètre.

    Par exemple j'ai ce défine
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    #define testDef(VAR) return (VAR);
     
    ...
    int fct()
    {
    ...
       testDef(-5)                  // doit être remplacé par return(--5);
    }
    comment puis-je remplacer
    testDef(VAR) par return (VAR); si VAR est > 0

    et par return (-VAR); sinon ?

    C'est possible de faire ça ?

  2. #2
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    C'est possible mais il ne faut pas. L'utilisation des #define pour définir une fonction est à proscrire.

    Ne cache surtout pas ton return dans une macro ton code sera ensuite incompréhensible, et non maintenable.

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Un define ne devrait définir que des valeurs, ou si vraiment tu y tiens, des expressions.
    return est une instruction, qu'il ne faut pas utiliser ainsi.

    Pour éviter des tas de problème, il faudrait toujours qu'une macro utilisable dans le code soit une valeur.

    Par contre, tu pourrais utiliser return M_TEST_VALEUR(-5).
    Du coup, c'est une sorte de fonction, que tu devrais définir comme telle.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    inline int testDef(int VAR) {return VAR < 0 ? -VAR : var;}
     
    ...
    int fct() {
    ...
       return testDef(-5);
    }

    Par contre, si la macro ne sert qu'au préprocesseur, c'est un autre problème.
    Les macros "fonctions" ne sont vraiment intéressantes que lorsque tu utilises les opérateurs magiques (# et ##).

  4. #4
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    Même pour définir des valeurs les macros n'apportent aucun avantage.

    Elles ne restent que par souci de compatibilité avec du vieux C++, mais je ne crois pas qu'elles doivent être utilisées pour autre chose que des directives préprocesseur prédéfinies, ou pour introduire des portions de code en mode Debug uniquement, etc...


    Pour définir une fonction, définis une fonction, comme l'exemple de @leternel. Pour définir une constante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #define toto 5 //bad practice 
    const int toto = 5;

    Autre chose :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     
    #define testDef(VAR) VAR > 0 ? return VAR : return -VAR
     
    int fct()
    {
    ...
       testDef(-5);
    }
     
    //En pre-processing, le define est trouvé dans fct et le code remplacé avant compilation et exécution...
     
    int fct()
    {
       -5 > 0 ? return -5 : return --5; 
    }
    Tu conçois que ton code ne vas pas te renvoyer 5 ou -5 (-- étant un opérateur de pré-incrémentation) ? (Si oui, tu conçois que c'est complètement tordu ?)

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 56
    Par défaut
    Merci, mais en fait j'avais simplement voulu simplifier mon exemple.

    Mon define me permet de surcharger les operateurs.
    voila le code exact
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    #define OperatorCastInt(OPE1, OPE2) \
    	ebovar &ebovar::operator OPE2 (const ebovar &right_op) \
    	{ \
    		int ope = ((var_type << 2) + right_op.var_type) & 15; \
    		switch(ope) \
    		{ \
    		case EBO_INT_INT:			i OPE2 right_op.i; break; \
    		case EBO_INT_FLOAT:		i OPE2 (int)right_op.f; break; \
    		case EBO_INT_STRING:		i OPE2 right_op.getInt(); break; \
    		case EBO_FLOAT_INT:		i = (int)f OPE1 right_op.i; break; \
    		case EBO_FLOAT_FLOAT:	i = (int)f OPE1 (int)right_op.f; break; \
    		case EBO_FLOAT_STRING:	i = (int)f OPE1 right_op.getInt(); break; \
    		case EBO_STRING_INT:		i = getInt() OPE1 right_op.i; break; \
    		case EBO_STRING_FLOAT:	i = getInt() OPE1 (int)f; break; \
    		case EBO_STRING_STRING:	i = getInt() OPE1 right_op.getInt(); break; \
    		default: \
    			printf("Error : can't apply operator OPE2 to this vartype (%s)\n", right_op.getType().c_str()); \
    			break; \
    		} \
    		return *this; \
    	} \
     \
    	ebovar &ebovar::operator OPE2 (int ivalue) \
    	{ \
    		switch(var_type) \
    		{ \
    		case EBO_INT:				i OPE2 ivalue; break; \
    		case EBO_FLOAT:			i = (int)f OPE1 ivalue; break; \
    		case EBO_STRING:			i = getInt() OPE1 ivalue; break; \
    		default: \
    			printf("Error : can't apply operator OPE2 to this vartype (%s)\n", getType().c_str()); \
    			break; \
    		} \
    		return *this; \
    	} \
     \
    	ebovar operator OPE1(const ebovar &left_op, const ebovar &right_op) \
    	{ \
    		int ope = ((left_op.var_type << 2) + right_op.var_type) & 15; \
    		switch(ope) \
    		{ \
    		case EBO_INT_INT:			return (ebovar)(left_op.i OPE1 right_op.i); break; \
    		case EBO_INT_FLOAT:		return (ebovar)(left_op.i OPE1 (int)right_op.f); break; \
    		case EBO_INT_STRING:		return (ebovar)(left_op.i OPE1 right_op.getInt()); break; \
    		case EBO_FLOAT_INT:		return (ebovar)((int)left_op.f OPE1 right_op.i); break; \
    		case EBO_FLOAT_FLOAT:	return (ebovar)((int)left_op.f OPE1 (int)right_op.f); break; \
    		case EBO_FLOAT_STRING:	return (ebovar)((int)left_op.f OPE1 right_op.getInt()); break; \
    		case EBO_STRING_INT:		return (ebovar)(left_op.getInt() OPE1 right_op.i); break; \
    		case EBO_STRING_FLOAT:	return (ebovar)(left_op.getInt() OPE1 (int)right_op.f); break; \
    		case EBO_STRING_STRING:	return (ebovar)(left_op.getInt() OPE1 right_op.getInt()); break; \
    		default: \
    			printf("Error : can't apply operator OPE1 to this vartype (%s OPE1 %s)\n", left_op.getType().c_str(), right_op.getType().c_str()); \
    			break; \
    		} \
    	} \
     \
    	ebovar operator OPE1(const ebovar &left_op, int ivalue) \
    	{ \
    		switch(left_op.var_type) \
    		{ \
    		case EBO_INT:       return (ebovar)(left_op.i OPE1 ivalue); break; \
    		case EBO_FLOAT:     return (ebovar)((int)left_op.f OPE1 ivalue);	break; \
    		case EBO_STRING:    return (ebovar)(left_op.getInt() OPE1 ivalue); break; \
    		default: \
    			printf("Error : can't apply operator OPE1 to this vartype (%s)\n", left_op.getType().c_str()); \
    			break; \
    		} \
    	} \
     \
    	ebovar operator OPE1(int ivalue, const ebovar &right_op) \
    	{ \
    		switch(right_op.var_type) \
    		{ \
    		case EBO_INT:			return (ebovar)(ivalue OPE1 right_op.i); break; \
    		case EBO_FLOAT:		return (ebovar)(ivalue OPE1 (int)right_op.f); break; \
    		case EBO_STRING:		return (ebovar)(ivalue OPE1 right_op.getInt()); break; \
    		default: \
    			printf("Error : can't apply operator OPE1 to this vartype (%s)\n", right_op.getType().c_str()); \
    			break; \
    		} \
    	}
    Ca fonctionne sans problème pour la plupart des opérateurs.
    Sauf que pour un seul opérateur, j'ai besoin d'opérer une petite modification.
    Alors évidement je peux très bien réaliser cet opérateur dans avoir recours au define, mais cela me semblait plus simple...

    Donc ma question est toujours d'actualité
    Comment changer une ligne de tout ce define au cas ou je l'appelle avec OP1 valant le caractère +

    Merci.

  6. #6
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    La surcharge des opérateurs ne devrait pas non plus être faite ainsi... ce n'est ni plus simple, ni une bonne chose à faire : essaie de refaire tout ton code sans utiliser les macros. Pour la réponse que tu attends je t'ai déjà donné un exemple mais tu ne dois pas les utiliser ainsi.

    Il ne s'agit que d'un alias qui va remplacé chaque appel au define par la portion de code en question.

  7. #7
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Juin 2008
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 56
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    #define testDef(VAR) VAR > 0 ? return VAR : return -VAR
    Tu conçois que ton code ne vas pas te renvoyer 5 ou -5 (-- étant un opérateur de pré-incrémentation) ? (Si oui, tu conçois que c'est complètement tordu ?)
    Merci je vais tester ça pur voir ce que ça donne.

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 147
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     
    #define testDef(VAR) VAR > 0 ? return VAR : return -VAR
     
    int fct()
    {
    ...
       testDef(-5);
    }
     
    //En pre-processing, le define est trouvé dans fct et le code remplacé avant compilation et exécution...
     
    int fct()
    {
       -5 > 0 ? return -5 : return --5; 
    }
    Ce code est faux, un return ne peut pas se trouver dans un opérateur ternaire.
    http://kukuruku.co/hub/cpp/secrets-o...rnary-operator point 5

    sinon les macros c'est comme le reste, très pratique, parfois indispensable, faut pas en abuser, mais pas non plus crier au bucher à leur moindre utilisation
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  9. #9
    Membre très actif

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Par défaut
    Honnêtement j'étais au travail (et sur plein d'autres langages que le C++), j'ai pas vraiment testé l'essentiel du propos étant surtout de preciser les dangers d'utilisation de ce genre de code. Ne pas crier au boucher certes, mais il faut utiliser les choses a bon escient et les macros sont tres rarement le moyen le plus avantageux dans le temps. En cela je suis donc en total désaccord et je penses également qu'il ne faut pas banaliser leur utiliation aupres des personnes qui viennent chercher des conseils ici, car vous n'en maîtrisez pas les effets de bord


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return VAR > 0 ? VAR : -VAR

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Inclure une Condition dans un "Where"
    Par the dude dans le forum Langage SQL
    Réponses: 4
    Dernier message: 22/02/2011, 08h42
  2. [JAR] Inclure une librairie dans un point jar
    Par Orionmel dans le forum Général Java
    Réponses: 5
    Dernier message: 08/11/2004, 22h25
  3. Introduire une condition dans une requete
    Par DeezerD dans le forum Langage SQL
    Réponses: 9
    Dernier message: 12/10/2004, 18h13
  4. [BCB6]Inclure une police dans un exécutable
    Par Bodom-Child dans le forum C++Builder
    Réponses: 8
    Dernier message: 20/08/2004, 11h18
  5. Inclure une dll dans une ressource
    Par bgcode dans le forum C++Builder
    Réponses: 4
    Dernier message: 21/08/2003, 11h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo