Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Константы


Автор: JAnty 28.3.2005, 13:04
Мне очень интересно, зачем константы которые занимают память, если есть макросы?

Автор: En_t_end 28.3.2005, 13:11
Тут недавно в подобной же теме все уже обьяснили, макросы тоже занимают память, глянь страницой 1-2 назад.
Добавлено @ 13:21
http://forum.vingrad.ru/index.php?showtopic=44313

Автор: chipset 28.3.2005, 13:29
Цитата(JAnty @ 28.3.2005, 02:04)
Мне очень интересно, зачем константы которые занимают память, если есть макросы?

Память все равно занимают.
Но кроме того, они не типизированы и их использование ведёт к ошибкам.

Автор: Alastis 28.3.2005, 13:50
Да, в больших проектах большое кол-во дефайнов чревато... хотя иногда это помогает сделать код красивым и понятным... для себяsmile

Автор: DENNN 28.3.2005, 15:37
Голосование составленно по дурацки.
Использование const и #define нужно не противопоставлять друг-другу, а использовать совместно так, как это для проекта удобнее.

Автор: pablo 28.3.2005, 16:57
Ребята давайте подумаем логически.
Если можно было бы обойтись без констант, только макросами, так зачем же их ввели ?
Ответ прост.
Потому что макросы встраиваются в код препроцессором,
повышают вероятность ошибок который очень тяжело находить.

Автор: S.A.P. 28.3.2005, 17:25
Не вижу смысла использовать const.
Добавлено @ 17:27
Цитата(chipset @ 28.3.2005, 13:29)
кроме того, они не типизированы
можно сдалеть типизированный дефайн

#define OUR_FLOAT (float)86,236
Добавлено @ 17:28
Современные компиляторы достаточно хорошо оптимизируют дефайны, и тот топ тому подтверждение.
Добавлено @ 17:29
Цитата(oleg1973 @ 28.3.2005, 17:25)
единственное отличие что при define данная строка , если она не используется нигде в программе, не будет включена в файл при компиляции

значит define круче


Автор: Олег М 28.3.2005, 18:01
Цитата(JAnty @ 28.3.2005, 13:04)
Мне очень интересно, зачем константы которые занимают память, если есть макросы?

А счего ты взял, что они занимают память? Это тоже самое, что и макросы, только для них, в отличие от макроса определён тип, а это хорошо.
Вообще в современном с++ можно спокойно обойтись без макросов, для того всё и делается.

Вообще с точки зрения призводительности и памяти отличий макросов от констант и инлайноских функций нет. А вот в с точки зрения хорошего и безопасного кода макросы уже давно не канают.


Автор: S.A.P. 28.3.2005, 18:12
Цитата
А вот в с точки зрения хорошего и безопасного кода макросы уже давно не канают
и в чем же заключается нехорошесть и опасность макросов?



Автор: Олег М 28.3.2005, 18:21
Цитата(Perchilla @ 28.3.2005, 18:12)
и в чем же заключается нехорошесть и опасность макросов?

В том что это не переменная, ни функция, простая глупая подстановка текста, которая не имеет ни типа, ни нормальных параметров. Макросы вообще плохо вписываются в парадигмы языков программирования.

Кстати, кто-нибудь может привести пример, на С++, более выгодного использования макросов в сравнении с константами и инлайновскими функциями?

Автор: JAnty 28.3.2005, 18:43
А почему во всех Header файах используют макросы?


Цитата
А счего ты взял, что они занимают память? Это тоже самое, что и макросы, только для них, в отличие от макроса определён тип, а это хорошо.


Да ещо как занимают.(помню чото в книге писалось про яейки памяти и Read Only).

- A что хорошего в сonst "определён тип"?
- Только путоница. smile

Автор: chipset 28.3.2005, 21:13
Хм.
Представьте вполне легальное обьявление:
Код

int abc = 3;

Теперь на секунду представьте, что какой-то крутой праграмер, написал:
Код

#define abc 1;
smile

Автор: S.A.P. 28.3.2005, 22:42
Если сравнивать константные объявления #define и const, то основное различие в том, что дефайн должен быть уникальным во всей программе, т.к. не чувствителен к пространствам имен. const в этом плане гораздо гибче, но иногда удобнее воспользоваться дефайном.

Ну а сравнивать дефайн и inline функции ИМХО глупо. 2 совершенно разные вещи.

Автор: chipset 28.3.2005, 22:47
Цитата(Perchilla @ 28.3.2005, 11:42)
иногда удобнее воспользоваться дефайном.

Пример в студию!

Автор: S.A.P. 29.3.2005, 08:00
Цитата(chipset @ 28.3.2005, 22:47)
Пример в студию!
например, когда мы точно не знаем, будет ли константа из подключаемого модуля задействована в нашей программе.

Автор: chipset 29.3.2005, 08:11
Цитата(Perchilla @ 28.3.2005, 21:00)
например, когда мы точно не знаем, будет ли константа из подключаемого модуля задействована в нашей программе.

Так тогда наоборот, у вас есть возможность определить собственную константу с таким-же именем, если я правильно понял.
...
Дело в том, что С++, как язык поддерживающий ООП в довольно-таки полной мере, применяет все vtnjls чтобы заставить людей мыслить обьектно-ориентированно. К примеру, существуют такие вещи как модификаторы private, public, protected; namespace'ы, защищенное наследование и т.д..
Это всё сделано, чтобы граммотный разработчик имел возможность контроллировать области видимости и реализовывать инкапсуляцию, при которой обьект представляет собой черный ящик. Будет весьма прикольно если какой то static обьект, предназначенный для namespace'а A, за непонятным хреном влезет в мой неймспейс B что случается при использовании абсолютно неконтроллируемого, пережитка Сишного прошлого - #define.
Невозможно никакое граммотное разделение кода на модули и классы при введении вышеупомянутого анахронизма. Это вполне применимо при маленьких проектах, тыща-две строк, но при отладке реальных программ это становится настоящей пыткой, и я был рад что в C# эта хренотень исчезла.

Автор: S.A.P. 29.3.2005, 08:26
Цитата(chipset @ 29.3.2005, 08:11)
Так тогда наоборот, у вас есть возможность определить собственную константу с таким-же именем, если я правильно понял.
не правильно понял.

простой пример
Код

#define a 1
const int b = 2;


2 константы: одна объявлена через define, вторая через const, обе не задействованы в программе. Смотрим ассемблерный код
Код

    #define a 1
    const int b = 2;
00411A1E  mov         dword ptr [b],2


как видишь компилятор пропустил define, а const остался в памяти. А теперь представь, что было бы, если все стандртные костантные значения (например WM_TIMER) были бы определены в через const.


Цитата(chipset @ 29.3.2005, 08:11)
и я был рад что в C# эта хренотень исчезла.
а вот этого делать не надо smile .

Автор: chipset 29.3.2005, 08:41
Код

#define a 1
const int j = 10;
int main()
{    
00411A00  push        ebp  
00411A01  mov         ebp,esp 
00411A03  sub         esp,0E4h 
00411A09  push        ebx  
00411A0A  push        esi  
00411A0B  push        edi  
00411A0C  lea         edi,[ebp-0E4h] 
00411A12  mov         ecx,39h 
00411A17  mov         eax,0CCCCCCCCh 
00411A1C  rep stos    dword ptr [edi] 
    int b = a;
00411A1E  mov         dword ptr [b],1 
    int c = a;
00411A25  mov         dword ptr [c],1 
    int y = j;
00411A2C  mov         dword ptr [y],0Ah ;не адрес переменной а число в хексе
}

Когда я добавил ещё одну константу но не заюзал её, код не изменился.

Автор: Олег М 29.3.2005, 08:54
Цитата(Perchilla @ 29.3.2005, 08:26)
а const остался в памяти. А теперь представь, что было бы, если все стандртные костантные значения (например WM_TIMER) были бы определены в через const.

А как ты компилил и на чём?

Цитата(Perchilla @ 29.3.2005, 08:26)
как видишь компилятор пропустил define,

smile думаешь компилятор вообще знал о нём, особенно если он, макрос, нигде не используется?

Автор: S.A.P. 29.3.2005, 13:08
Цитата(chipset @ 29.3.2005, 08:41)
Когда я добавил ещё одну константу но не заюзал её, код не изменился.
ты сделал константу глобальной. Разницы между define и const в данном случае нет. Это результат оптимизации компилера.

А попробуй - ка сделать ее не глобальной.
Код

void func()
{
     const int j = 10;
     return;
};

int _tmain(int argc, _TCHAR* argv[])
{
    func();
    return 0;
}

и посмотри дизасмом. Память по любому будет выделяться. Юзаешь ты ее или нет.
Дефайн я в любом месте объявлю и он будет глобальный и память выделяться не будет, если я его не использую. Дело вкуса. smile .

и наконец твой код. Попробуй вместо const int j = 10; записать
const double j = 10; smile . 32 битный ассемблер не сможет 8 байт передать за раз и все равно придется выделять память под константу. А int напрямую передает, потому что так быстрее. Компилер, гад все оптимизирует.

Цитата
smile думаешь компилятор вообще знал о нём, особенно если он, макрос, нигде не используется?
а зачем ему знать, если константа не юзается?

Добавлено @ 13:18
Олег М есть еще одно применение #define.

Из WINDOWSX
Код

#define HANDLE_WM_DESTROY(hwnd, wParam, lParam, fn) \
((fn) (hwnd), 0L)
#define HANDLE_MSG(hwnd, message, fn) \
case (message) : return HANDLE_##message((hwnd), (wParam), (lParam), (fn))


юзаем

Код

switch(Message)
{
   HANDLE_MSG(hwnd, WM_DESTROY, OnDestroy);
. . . . 
}


Удобно? Как такое инлайновыми функциями сделать?

Что не говорите, но #define жил, живет и будет жить. Во всяком случае в C++.

Автор: DENNN 29.3.2005, 13:47
Цитата(Perchilla @ 29.3.2005, 13:08)
Что не говорите, но #define жил, живет и будет жить.

А никто и не спорит smile

Автор: Олег М 29.3.2005, 14:20
Цитата(Perchilla @ 29.3.2005, 13:08)
Удобно? Как такое инлайновыми функциями сделать?

smile Может и удобно, ещё бы понять - зачем?

Цитата(Perchilla @ 29.3.2005, 13:08)
и посмотри дизасмом. Память по любому будет выделяться. Юзаешь ты ее или нет.

Покажи, что у тебя в дизасме получается (есть подозрение, что ты в дебаге компилишь). Лично у меня вот что
Код

int func()
{
    const int n=0xABC;
    return n;
}

int main ()
{

    int n=1;
    n+=func();
    std::cout<<n;
004014B0  push        0ABDh 
004014B5  mov         ecx,offset std::cout (4151F0h) 
004014BA  call        std::basic_ostream<char,std::char_traits<char> >::operator<< (401320h) 
    return n;
004014BF  mov         eax,0ABDh 
}
004014C4  ret         

Где тут подо что память выделяется? непонятно

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)