| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > про компилятор |
| Автор: oleg1973 3.3.2005, 17:03 |
| вот интересно чем с точки зрения компилятора отличается define nome="vasya pupkin" и char []="vasya pupkin" при компиляции компилер сделает секцию данных и засунет туда эту строку (есть опция пихать данный в секцию кода, сэкономим на размере) тоесть я так предполагаю конечный вариант будет одинаков нафига тогда было делать такие заморочки? |
| Автор: En_t_end 3.3.2005, 17:14 |
| Просто во втором случае мы получим массив - это есть очень хорошо, так как мы можем работать с ним, как с матрицей(всевозможные отдельносимвольные преобразования доступны). |
| Автор: chipset 3.3.2005, 17:17 |
| Дефайны не рекомендуется кстати использовать в C++. |
| Автор: oleg1973 3.3.2005, 17:18 |
| с точки зрения нахождения в памяти обеих примеров они оба всего лиш последовательность asciz vasya pupkin, byte 0 все, ниче там спецального нет |
| Автор: Дрон 3.3.2005, 17:21 |
| oleg1973 Если ты написал дефайн, то эта строка будет подставляться во все места, где ты её используешь. При этом если ты не включил опцию merge duplicate strings (или как там она зовётся), то для каждого раза будет выделена своя память. При определении массива, ты выделяешь память только один раз. С точки зрения компилятора, то же самое: либо много копий строки в екзешнике, либо одна. |
| Автор: En_t_end 3.3.2005, 17:22 |
| define nome="vasya pupkin" пожалуйста попробуй вывести на экран только букву u со вторым же случаем все легко и просто : cout << massiv[7]; |
| Автор: oleg1973 3.3.2005, 17:23 | ||
бред полный , покрайне мере дял open watcom C строка в сегменте данных а в коде указатель на нее |
| Автор: Дрон 3.3.2005, 17:34 | ||
Сейчас проверю Только у меня watcom нету. Добавлено @ 17:43 Да. Похоже я не прав. Компилятор не так уж глуп, и в файле строка встречается только один раз (Visual C++ 2003) Но первое высказывание остаётся верным -- при исполнении память выделяется отдельно для каждой встреченной строки. |
| Автор: srd 3.3.2005, 17:46 |
| oleg1973 Разницу между препроцессором и компилятором знаешь? Во втором варианет ты создаешь символьный литерал и указатель на него. А в варианте с define'ом препроцессор просто заменяет одну последовательность символов другой до компиляции, а потому результат может быть другой, завист от того, как ты этот макрос использовал. |
| Автор: oleg1973 3.3.2005, 21:00 | ||
| ой знатоки блин как всегда все самому нада проверять проверил вывод: после компиляции как я и говорил все одинаково что char что define вот код
в вот кусок его дизасма Segment: CONST DWORD USE32 0000000D bytes 0000 L$4: 0000 70 75 70 6B 69 6E 20 76 61 73 79 61 00 pupkin vasya. Segment: _DATA DWORD USE32 0000000D bytes 0000 _ass2: 0000 76 61 73 79 61 20 70 75 70 6B 69 6E 00 vasya pupkin. имеем 2 секции данных с двумя asciz string которые потом используются таким макаром printf("%s,%s",ass1,ass2); 0018 L$1: 0018 B8 00 00 00 00 mov eax,offset _ass2 001D 50 push eax 001E B8 00 00 00 00 mov eax,offset L$4 0023 50 push eax 0024 B8 0D 00 00 00 mov eax,offset L$5 0029 50 push eax 002A E8 00 00 00 00 call printf_ все никаких тут фокусов нет единственное отличие что при define данная строка , если она не используется нигде в программе, не будет включена в файл при компиляции значит define круче |
| Автор: bel_nikita 3.3.2005, 22:46 | ||||
Однако, не одинаково:
З.Ы.: В догонку http://www.rsdn.ru/?Forum/?uid=27140 |
| Автор: oleg1973 4.3.2005, 02:11 |
| однако одинаково |
| Автор: Ni@m 4.3.2005, 03:40 | ||
Дело в том, что дефайн - директива препроцессора, и получаетс так, то компилятор думает, что это уже готовая строка, те const char*. Поэтому разница есть! Да ктати
запросто =) |
| Автор: srd 4.3.2005, 06:03 | ||||||||||
| oleg1973 Что-то я понять не могу, что ты хочешь доказать. Оптимизация символьных литералов выполнянется в любом случае, и при этом компилятору с линкером по барабану, как ты эти литералы ввёл - макросами или языковыми средствами.
Unreferenced variables будут также выброшены при оптимизации, так что ничем здесь #define не круче. А вот: наличие #undef возможность написать #define ещё раз (в лучшем случае компилятор выдаст warning "macro redefinition"). область видимости #define не ограничивается блоком, в котором был введён, а простирается от строчки с #define до конца исходного модуля. тупая замена символов препроцессором без учета, в каком качестве был использован идентификатор - в качестве имени переменной, типа или функции и т.п. Всё это делает такой способ введения констант полным отстоем. Давай договоримся, про какой язык мы говорим - Си или Си++? В "классическом" Си типом символьного литерала является char *, а в Си++ - const char *, но при этом оставлена для совместимости возможность присвоить символьный литерал объекту типа char *. Отсюда расхождения в показаниях. Эта строка будет скомпилирована и в Си, и в Си++, но в первом случае она отработает, а во втором - свалит программу во время выполнения.
Эта строка является допустимой в Си, но в Си++ не скомпилируется.
И как посоветовал bel_nikita, обрати внимание на разницу между этим
и этим
В первом случае мы получем два указателя на единственный символьный литерал, во втором - два разных объекта, каждый из которых содержит свою копию "string". Так что фокусы c define справедливо сравнивать с первым вариантом, но не вторым. |
| Автор: En_t_end 4.3.2005, 06:04 |
| Ni@m Мда... я уже понял, что чушь сморозил. Все равно лучше юзать нормальный символьный массив. Косвенная переносимость будет выше, может быть в другом компиляторе дефайны обрабатываются по-другому и потом будешь расхлебывать кашу из 100 неработающих строк. |