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

Броски имеют в виду разные вещи в зависимости от того, каковы они. Они могут просто быть переименованиями типа данных без изменения в представленных битах (большинство бросков между целочисленными типами, и указатели похожи на это), или преобразования, которые даже не сохраняют длину (такой как между двойным и международным на большинстве компиляторов). Во многих случаях значение броска является просто неуказанным, означая, что компилятор должен сделать что-то разумное, но не должен документировать точно что.

бросок А не должен даже приводить к применимому значению. Что-то как char * cp; float * fp; cp = malloc(100); fp = (float *)(cp + 1); почти наверняка приведет к неправильно выровненному указателю на плавание, которое разрушит программу в некоторых системах, если программа попытается использовать его.

28
задан Nawaz 22 January 2011 в 12:44
поделиться

4 ответа

Рассмотрим этот код,

#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;
}

Очевидно, что каждое умножение приводит к ошибке компиляции, , но посмотрите, как GCC генерирует сообщения для каждой ошибки умножения:

prog.cpp: 19: ошибка: нет соответствия для 'operator *' в 'eWidth * s'
prog.cpp: 20: ошибка: нет соответствия для 'operator *' в '300 * s '
prog.cpp: 21: ошибка: нет совпадения для' operator * 'в' Width * s '

В сообщении об ошибке вы не видите макрос WIDTH который у тебя #defined, верно? Это потому, что к тому времени, когда GCC делает любую попытку компилировать строку, соответствует второй ошибке, он не видит WIDTH, все видит только 300, как до того, как GCC компилирует строку, препроцессор уже уже заменил WIDTH на 300. С другой стороны, ничего подобного не происходит с enum eWidth и const Width.

См. Ошибку здесь: http://www.ideone.com/naZ3P


Также прочитайте Item 2 : Prefer consts, enums, and inlines to #defines из Effective C ++ Скотт Мейерс.

30
ответ дан 28 November 2019 в 03:07
поделиться

enum - это постоянная времени компиляции с отладочной информацией без выделения памяти.

const выделяется с хранилищем, в зависимости от того, оптимизирован ли он компилятором с постоянным распространением.

#define не имеет выделения памяти.

14
ответ дан 28 November 2019 в 03:07
поделиться

Компилятор сохраняет информацию перечисления в двоичном виде, когда программа компилируется с определенными параметрами.

Когда переменная имеет тип enum, отладчик может показывать имя enum. Это лучше всего показать на примере:

enum E {
    ONE_E = 1,
};

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

    return 0;
}

Если вы скомпилируете это с помощью gcc -g, вы можете попробовать следующее в 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) 

Если вы использовали , у вас не будет правильного типа, чтобы дать e, и вам придется использовать целое число. В этом случае компилятор напечатает 1 вместо ONE_E.

Флаг -g просит gdb добавить отладочную информацию в двоичный файл. Вы даже можете увидеть, что это там, выпуская:

xxd test | grep ONE_E

Я не думаю, что это будет работать во всех архитектурах, однако.

3
ответ дан 28 November 2019 в 03:07
поделиться

Проверьте следующую статью, хорошее резюме http://www.queryhome.com/26340/define-vs-enum-vs-constant

0
ответ дан 28 November 2019 в 03:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: