macros - C++-enum vs.const vs#define





constants enumeration (7)


Considérez ce code,

#define WIDTH 300

enum econst
{
   eWidth=300
};

const int Width=300;

struct sample{};

int main() 
{
        sample s;
        int x = eWidth * s; //error 1
        int y = WIDTH * s;  //error 2
        int z = Width * s;  //error 3
        return 0;
}

Evidemment, chaque multiplication entraîne une erreur de compilation, mais voyez comment le GCC génère les messages pour chaque erreur de multiplication:

prog.cpp: 19: erreur: pas de correspondance pour 'operator *' dans 'eWidth * s'
prog.cpp: 20: erreur: pas de correspondance pour 'operator *' dans '300 * s'
prog.cpp: 21: erreur: pas de correspondance pour 'operator *' dans 'Width * s'

Dans le message d'erreur, vous ne voyez pas la macro WIDTH que vous avez #defined , n'est-ce pas? En effet, au moment où GCC tente de compiler la ligne correspond à la seconde erreur, il ne voit pas WIDTH , tout ce qu’il ne voit que 300, car avant que GCC ne compile la ligne, le préprocesseur a déjà remplacé WIDTH par 300. De l’autre main, il n'y a pas une telle chose se passe avec enum eWidth et const Width .

Voir l'erreur vous-même ici: http://www.ideone.com/naZ3P

Lisez également le Item 2 : Prefer consts, enums, and inlines to #defines de Effective C ++ par Scott Meyers.

À la fin de l'article ici: http://www.learncpp.com/cpp-tutorial/45-enumerated-types/ , il mentionne ce qui suit:

Enfin, comme pour les variables constantes, les types énumérés apparaissent dans le débogueur, ce qui les rend plus utiles que les valeurs définies à cet égard .

Comment la phrase en gras ci-dessus est-elle atteinte?

Merci.




Au moins pour Visual Studio 2008 dont je dispose actuellement, cette phrase est correcte. Si tu as

#define X 3
enum MyEnum
{
    MyX = 3
};

int main(int argc, char* argv[])
{
    int i = X;
    int j = (int)MyX;
    return 0;
}

et vous définissez un breakpont dans main , vous pouvez passer votre souris sur "MyX" et voir qu'il est évalué à 3. Vous ne voyez rien d'utile si vous passez la souris sur X.

Mais ce n'est pas une propriété de langage mais plutôt un comportement d'IDE. Les versions suivantes peuvent le faire différemment, ainsi que d'autres IDE. Il suffit donc de vérifier pour votre IDE pour voir si cette phrase s'applique dans votre cas.







Le compilateur stocke les informations enum dans le binaire lorsque le programme est compilé avec certaines options.

Lorsqu'une variable est d'un type enum, un débogueur peut afficher le nom de l'énumération. Ceci est mieux illustré avec un exemple:

enum E {
    ONE_E = 1,
};

int main(void)
{
    enum E e = 1;

    return 0;
}

Si vous compilez cela avec gcc -g vous pouvez essayer ce qui suit dans gdb :

Reading symbols from test...done.
(gdb) b main
Breakpoint 1 at 0x804839a: file test.c, line 8.
(gdb) run
Starting program: test 

Breakpoint 1, main () at test.c:7
7               enum E e = 1;
(gdb) next
9               return 0;
(gdb) print e
$1 = ONE_E
(gdb) 

Si vous utilisiez une définition, vous n'auriez pas un type approprié pour donner e , et vous devriez utiliser un entier. Dans ce cas, le compilateur imprimera 1 au lieu de ONE_E .

L' -g demande à gdb d'ajouter des informations de débogage au fichier binaire. Vous pouvez même voir que c'est là en émettant:

xxd test | grep ONE_E

Je ne pense pas que cela fonctionnera dans toutes les architectures.




#define valeurs #define sont remplacées par le pré-processeur avec la valeur qu'elles déclarent, donc dans le débogueur, il ne voit que la valeur, pas le nom #defined, par exemple si vous avez #define NUMBER_OF_CATS 10, dans le débogueur voir seulement 10 (puisque le pré-processeur a remplacé toutes les instances de NUMBER_OF_CATS dans votre code par 10).

Un type énuméré est un type en lui-même et les valeurs sont des instances constantes de ce type. Ainsi, le pré-processeur le laisse seul et vous verrez la description symbolique de la valeur dans le débogueur.




Je réponds trop tard mais je sens que je peux ajouter quelque chose - enum vs const vs #define

enum -

  1. Ne nécessite pas de valeurs d'assemblage (si vous voulez simplement avoir des valeurs séquentielles 0, 1, 2 ..) alors que dans le cas de #defines, vous devez gérer manuellement des valeurs qui pourraient provoquer des erreurs humaines dans le passé
  2. Cela fonctionne tout aussi variable que lors du débogage en ligne, la valeur de enum peut être regardée dans la fenêtre de surveillance
  3. Vous pouvez avoir une variable de type enum à laquelle vous pouvez assigner une énumération

    numéros de type typedef {DFAULT, CASE_TRUE, CASE_OTHER,};

    int main (void) {nombre nombre = CASE_TRUE; }

const -

  1. Il est stocké en permanence dans la zone de lecture seule de la mémoire, mais il est possible d'y accéder en utilisant l'adresse qui n'est pas possible dans le cas de #define
    1. Vous avez le type check dans votre main si vous utilisez const plutôt que #define
  2. définit une directive de pré-traitement mais const est un temps de compilation par exemple

    const char * name = "vikas";

Vous pouvez accéder au nom et utiliser son adresse de base pour lire les noms tels que vikas [3] pour lire «a», etc.

#defines - sont des directives de préprocesseur muettes qui font le remplacement textuel




J'ai écrit un programme de test rapide pour démontrer une différence:

#include <stdio.h>

enum {ENUM_DEFINED=16};
enum {ENUM_DEFINED=32};

#define DEFINED_DEFINED 16
#define DEFINED_DEFINED 32

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

   printf("%d, %d\n", DEFINED_DEFINED, ENUM_DEFINED);

   return(0);
}

Cela compile avec ces erreurs et avertissements:

main.c:6:7: error: redefinition of enumerator 'ENUM_DEFINED'
enum {ENUM_DEFINED=32};
      ^
main.c:5:7: note: previous definition is here
enum {ENUM_DEFINED=16};
      ^
main.c:9:9: warning: 'DEFINED_DEFINED' macro redefined [-Wmacro-redefined]
#define DEFINED_DEFINED 32
        ^
main.c:8:9: note: previous definition is here
#define DEFINED_DEFINED 16
        ^

Notez que enum donne une erreur quand define donne un avertissement.





c++ macros constants enumeration