No final do artigo aqui: http://www.learncpp.com/cpp-tutorial/45-enumerated-types/ , ele menciona o seguinte:
Finalmente, como acontece com as variables constantes, os tipos enumerados aparecem no depurador, tornando-os mais úteis do que os valores #definidos nesse aspecto .
Como a frase em negrito acima é alcançada?
Obrigado.
Considere este código,
#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; }
Obviamente, cada multiplicação resulta em erro de compilation, mas veja como o GCC gera as mensagens para cada erro de multiplicação:
prog.cpp: 19: erro: nenhuma correspondência para ‘operator *’ em ‘eWidth * s’
prog.cpp: 20: erro: nenhuma correspondência para ‘operator *’ em ‘300 * s’
prog.cpp: 21: erro: nenhuma correspondência para ‘operator *’ em ‘Width * s’
Na mensagem de erro, você não vê a macro WIDTH
que você #defined
, certo? Isso ocorre porque no momento em que o GCC faz qualquer tentativa de compilar a linha corresponde ao segundo erro, ele não vê WIDTH
, tudo o que ele vê é apenas 300, como antes o GCC compila a linha, o pré-processador já substituiu WIDTH
por 300. Por outro Por outro lado, não existe tal coisa acontece com enum eWidth
e const Width
.
Veja o erro você mesmo aqui: http://www.ideone.com/naZ3P
Além disso, leia o Item 2 : Prefer consts, enums, and inlines to #defines
from Effective C ++ por Scott Meyers.
enum
é constante de tempo de compilation com informações de debugging sem alocação de armazenamento.
const
é alocado com um armazenamento, dependendo se é otimizado pelo compilador com propagação constante.
#define
não tem alocação de armazenamento.
#define
valores são substituídos pelo pré-processador com o valor que eles são declarados como, portanto, no depurador, ele só vê o valor, não o #defined name, por exemplo, se você tiver #define NUMBER_OF_CATS 10, no debugger você veja apenas 10 (já que o pré-processador substituiu cada instância de NUMBER_OF_CATS em seu código por 10.
Um tipo enumerado é um tipo em si mesmo e os valores são instâncias constantes desse tipo e, portanto, o pré-processador o deixa sozinho e você verá a descrição simbólica do valor no depurador.
O compilador armazena informações enum no binário quando o programa é compilado com certas opções.
Quando uma variável é do tipo enum, um depurador pode mostrar o nome do enum. Isso é melhor mostrado com um exemplo:
enum E { ONE_E = 1, }; int main(void) { enum E e = 1; return 0; }
Se você compilar com o gcc -g
você pode tentar o seguinte no 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)
Se você usou um define, você não teria um tipo apropriado para dar e
, e teria que usar um inteiro. Nesse caso, o compilador imprimiria 1
vez de ONE_E
.
O sinalizador -g
pede ao gdb para adicionar informações de debugging ao binário. Você pode até ver que está lá, emitindo:
xxd test | grep ONE_E
Eu não acho que isso funcionará em todas as arquiteturas, no entanto.
Pelo menos para o Visual Studio 2008 que tenho atualmente em mãos, esta frase está correta. Se você tem
#define X 3 enum MyEnum { MyX = 3 }; int main(int argc, char* argv[]) { int i = X; int j = (int)MyX; return 0; }
e você definir um breakpont no main
, você pode passar o mouse sobre “MyX” e ver que ele é avaliado como 3. Você não vê nada útil se você passar o mouse sobre X.
Mas isso não é uma propriedade de linguagem, mas sim um comportamento IDE. As próximas versões podem ser diferentes, assim como outras IDEs. Então, basta verificar para o seu IDE para ver se esta frase se aplica no seu caso.
Estou respondendo tarde demais, mas sinto que posso acrescentar algo – enum vs. const vs. #define
enum –
Você pode ter uma variável do tipo enum à qual você pode atribuir um enum
typedef enum numbers {DFAULT, CASE_TRUE, CASE_OTHER,};
int main (void) {número de números = CASE_TRUE; }
const –
define são diretiva de pré-processamento, mas const é tempo de compilation, por exemplo
const char * name = “vikas”;
Você pode acessar o nome e usar seu endereço base para ler o tal como vikas [3] para ler ‘a’ etc.
#defines – são diretivas de pré-processador idiotas que substituem textualmente
Verifique o seguinte artigo, bom resumo http://www.queryhome.com/26340/define-vs-enum-vs-constant