Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > 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 smile
со вторым же случаем все легко и просто :
cout << massiv[7];

Автор: oleg1973 3.3.2005, 17:23
Цитата
то эта строка будет подставляться во все места, где ты её используешь

бред полный , покрайне мере дял open watcom C
строка в сегменте данных
а в коде указатель на нее

Автор: Дрон 3.3.2005, 17:34
Цитата(oleg1973 @ 3.3.2005, 17:23)
бред полный , покрайне мере дял open watcom C
строка в сегменте данных
а в коде указатель на нее

Сейчас проверю smile
Только у меня watcom нету.
Добавлено @ 17:43
Да. Похоже я не прав.
Компилятор не так уж глуп, и в файле строка встречается только один раз (Visual C++ 2003)

Но первое высказывание остаётся верным -- при исполнении память выделяется отдельно для каждой встреченной строки.

Автор: srd 3.3.2005, 17:46
oleg1973
Разницу между препроцессором и компилятором знаешь? Во втором варианет ты создаешь символьный литерал и указатель на него. А в варианте с define'ом препроцессор просто заменяет одну последовательность символов другой до компиляции, а потому результат может быть другой, завист от того, как ты этот макрос использовал.

Автор: oleg1973 3.3.2005, 21:00
ой знатоки блин smile
как всегда все самому нада проверять
проверил
вывод:
после компиляции как я и говорил все одинаково что char что define

вот код
Код

#include <stdio.h>

#define ass1 "pupkin vasya"

char ass2[]="vasya pupkin";

void main()
{
printf("%s,%s",ass1,ass2);
}


в вот кусок его дизасма

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_

все никаких тут фокусов нет smile

единственное отличие что при define данная строка , если она не используется нигде в программе, не будет включена в файл при компиляции

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

Автор: bel_nikita 3.3.2005, 22:46
Цитата
вывод:
после компиляции как я и говорил все одинаково что char что define

Однако, не одинаково:
Код

#include <stdio.h>

#define ass1 "pupkin vasya" /* THIS IS CONSTANT */

char ass2[]="vasya pupkin"; /* IS NOT CONSTANT */

void main()
{
 memset(ass2,0x30,5);
 memset(ass1,0x30,5);
 ass2[0] = 'X';  
 ass1[0] = 'X';
 printf("%s,%s",ass1,ass2);
}
smile
З.Ы.: В догонку
http://www.rsdn.ru/?Forum/?uid=27140

Автор: oleg1973 4.3.2005, 02:11
однако одинаково

Автор: Ni@m 4.3.2005, 03:40
Дело в том, что дефайн - директива препроцессора, и получаетс так, то компилятор думает, что это уже готовая строка, те const char*. Поэтому разница есть! Да ктати
Цитата(En_t_end @ 3.3.2005, 17:22)
define nome="vasya pupkin"
пожалуйста попробуй вывести на экран только букву u smile

запросто =)

Автор: srd 4.3.2005, 06:03
oleg1973
Что-то я понять не могу, что ты хочешь доказать. Оптимизация символьных литералов выполнянется в любом случае, и при этом компилятору с линкером по барабану, как ты эти литералы ввёл - макросами или языковыми средствами.

Цитата
единственное отличие что при define данная строка , если она не используется нигде в программе, не будет включена в файл при компиляции

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

Unreferenced variables будут также выброшены при оптимизации, так что ничем здесь #define не круче.
А вот:
наличие #undef
возможность написать #define ещё раз (в лучшем случае компилятор выдаст warning "macro redefinition").
область видимости #define не ограничивается блоком, в котором был введён, а простирается от строчки с #define до конца исходного модуля.
тупая замена символов препроцессором без учета, в каком качестве был использован идентификатор - в качестве имени переменной, типа или функции и т.п.
Всё это делает такой способ введения констант полным отстоем.

Давай договоримся, про какой язык мы говорим - Си или Си++? В "классическом" Си типом символьного литерала является char *, а в Си++ - const char *, но при этом оставлена для совместимости возможность присвоить символьный литерал объекту типа char *. Отсюда расхождения в показаниях.

Эта строка будет скомпилирована и в Си, и в Си++, но в первом случае она отработает, а во втором - свалит программу во время выполнения.
Код

memset(ass1,0x30,5);


Эта строка является допустимой в Си, но в Си++ не скомпилируется.
Код

ass1[0] = 'X';


И как посоветовал bel_nikita, обрати внимание на разницу между этим
Код

const char *p = "string";
const char *q = "string";

и этим
Код

const char p[] = "string";
const char q[] = "string";

В первом случае мы получем два указателя на единственный символьный литерал, во втором - два разных объекта, каждый из которых содержит свою копию "string". Так что фокусы c define справедливо сравнивать с первым вариантом, но не вторым.

Автор: En_t_end 4.3.2005, 06:04
 Ni@m 
Мда... я уже понял, что чушь сморозил.
Все равно лучше юзать нормальный символьный массив. Косвенная переносимость будет выше, может быть в другом компиляторе дефайны обрабатываются по-другому и потом будешь расхлебывать кашу из 100 неработающих строк.

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