вопрос к знатокам #define - страница 3

 
Alexandr Andreev:


Вроде все понимают.....

Так что это для тех кто только начинает свой путь....

Можно это все еще в стат класс обернуть и возвращать ссылку которой потом приравнивать остатки т.к. у данного способа есть минус при работе с if (a!=5) Print(a);  так работать не будет, нужно обязательно написать  if (a!=5) {Print(a);}, в классах можно этот момент подправить, но лень)) а в обще это вроде все есть в архивах истории

способ с классами инициализиурем наши данные через статичный метод и объединяем оператором вызов нашего принта.... тогда  if (a!=5) Print(a); , будет работать

Это все от лени. Увлекся, но забил. Сократил что то, но до разумного.  К тому же принты, записи в файл это либо сбор данных, либо отработка алгоритма, настройка. А если забить предопределенные стринги в принт, то запятые будут печататься. В общем это мозг тренирует конечно, но даже путь не кажет.

 
Alexandr Andreev:



Dmitry Fedoseev:


Vladimir Simakov:


Раз уж так сложилось, можно вопрос. Чем дефайн отличается от вызова функции для компилятора. Пришел в выводу что ничем. Ошибаюсь?

 
Valeriy Yastremskiy:

Раз уж так сложилось, можно вопрос. Чем дефайн отличается от вызова функции для компилятора. Пришел в выводу что ничем. Ошибаюсь?

Дефайн - подстановка во время ДО компиляции, поэтому всякие __LINE__ становятся именно такими какими и должны быть, можно подставлять неполноценный отрывок кода

А функция это во многих языках ссылка на код (goto), а в других подстановка кода (разворачивание всех функций) во время создания исполняемого файла.

Ну и еще дефанй это типо зло, т.к. усложняет поиск ошибок, поэтому хороший дефайн - это когда его нету 
 
Alexandr Andreev:

Дефайн - подстановка во время ДО компиляции, поэтому всякие __LINE__ становятся именно такими какими и должны быть, можно подставлять неполноценный отрывок кода

А функция это во многих языках ссылка на код (goto), а в других подстановка кода (разворачивание всех функций) во время создания исполняемого файла.

Вопрос в отношении МКЛ. Я правильно понимаю  goto в исполняемом файле нет, кроме циклов. Вопрос возник из особенностей компиляции. Строго сверху вниз. И если переменную объявить внизу тела цикла, а вызвать ее в условиях цикла будет предупреждение. Вывод проверка сверху вниз. И исполняемый файл формируется подстановкой функций, как дефайн, а не  ссылками goto.

 
Alexandr Andreev:

Дефайн - подстановка во время ДО компиляции, поэтому всякие __LINE__ становятся именно такими какими и должны быть, можно подставлять неполноценный отрывок кода

А функция это во многих языках ссылка на код (goto), а в других подстановка кода (разворачивание всех функций) во время создания исполняемого файла.

То есть подстановка влияет только на скорость сборки при компиляции?
И это рационально только для сборки больших проектов?
Или всё таки задефайненый код будет быстрее выполнятся в исполняемом файле?

 
Valeriy Yastremskiy:

Вопрос в отношении МКЛ. Я правильно понимаю  goto в исполняемом файле нет, кроме циклов. Вопрос возник из особенностей компиляции. Строго сверху вниз. И если переменную объявить внизу тела цикла, а вызвать ее в условиях цикла будет предупреждение. Вывод проверка сверху вниз. И исполняемый файл формируется подстановкой функций, как дефайн, а не  ссылками goto.

Нет, в 2008 году у мкл точно использовался способ ссылки на код. 

Используется ли сейчас полное разворачивание - тут не явно.

Сейчас написание своего компилятора это 3-4 курс любого факультета информатики,

И там бывает все запутанно, где то ссылки де то раскрытие, в общем кто как хочет так и пишет.

Скорее всего разворачивают что можно, но не всё. Понятно что операторы типо for и т.д. это совсем другая история.

 
Roman:

То есть подстановка влияет только на скорость сборки при компиляции?
И это рационально только для сборки больших проектов?
Или всё таки задефайненый код будет быстрее выполнятся в исполняемом файле?

Развертывание обычных функций - это само собой

т.е. к примеру for (int i=0; i<ArraiSize(max); i++)

тут  ArraiSize(max); разворачивается и там получается что то типо адреса на размер данного массива (если расматривать масив то у него есть в перемнной его размер, и вот тут проходит подстановка на эту переменную "адрес в памяти") т.е. нет смысла самому менять его на переменную, вообще.

 for (int i=0; i<ArraiSize(max); i++)

и

for (int i=0; i<size; i++) 

В данному случае  ArraiSize(max) и  size имеют одинаковые тайминги к определению значения размера массива

 
Alexandr Andreev:

Нет, в 2008 году у мкл точно использовался способ ссылки на код. 

Используется ли сейчас полное разворачивание - тут не явно.

Сейчас написание своего компилятора это 3-4 курс любого факультета информатики,

И там бывает все запутанно, где то ссылки де то раскрытие, в общем кто как хочет так и пишет.

Скорее всего разворачивают что можно, но не всё. Понятно что операторы типо for и т.д. это совсем другая история.

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

 
Roman:

То есть подстановка влияет только на скорость сборки при компиляции?
И это рационально только для сборки больших проектов?
Или всё таки задефайненый код будет быстрее выполнятся в исполняемом файле?

1 - наверное да но на микросекунды =)

2 - скорее наоборот - надо использовать максимально краткие дефайны и по минимуму

3 - в 2008 году это утверждение было бы верным для мкл4. А вот сейчас скорость будет одинакова

 
Alexandr Andreev:

Развертывание обычных функций - это само собой

т.е. к примеру for (int i=0; i<ArraiSize(max); i++)

тут  ArraiSize(max); разворачивается и там получается что то типо адреса на размер данного массива (если расматривать масив то у него есть в перемнной его размер, и вот тут проходит подстановка на эту переменную "адрес в памяти") т.е. нет смысла самому менять его на переменную, вообще.

 for (int i=0; i<ArraiSize(max); i++)

и

for (int i=0; i<size; i++) 

В данному случае  ArraiSize(max) и  size имеют одинаковые тайминги к определению значения размера массива

В этом примере цикла, наверно не соглашусь про тайминги.
Рекомендуют наоборот, получить результат в переменную size, и её уже использовать в условии.
Так как цикл на каждой итерации для ArraiSize(max), будет делать лишнее разворачивание, замедляя выполнение цикла.
То есть лишние инструкции в ассемблерном коде.

Причина обращения: