- ά ν θ ρ ω π ο ς -
Мои универсальные макросы https://github.com/anthrwpos1/macros
Почему Вы ищете между ними разницу. Они обе виртуальные, они играют роль связи и не более того. Потому что, они не энергонезависимые, на них нет ссылки из визуализации или откуда то еще. Они нужны только лишь для связи внутри макроса и все. Поэтому компилятор в реальности эти переменные не создает для прибора. Поэтом то Вы и видите всегда 0 в просмотрщике. Но по Вашему недоумению понимаю, что нужно еще предпринять какие-то разъяснительные шаги в лоджике.
программер
Можете ещё какими-нибудь словами мысль выразить?
Термин "inline функция", полагаю, подразумевается из C/C++. Но совершенно непонятно почему вы напираете на слово inline.
Дело в том, что в этих языках наличие или отсутствие модификатора inline не влияет на результат программы.
Иными словами, inline функция и точно такая же не-inline будут работать совершенно одинаково, а сам признак inline это лишь подсказка компилятору, влияющая на скорость работы программы, но не на результат.
Вообще говоря, подставляет ли компилятор код макроса каждый раз или компилирует макрос единожды -- не так важно для пользователей ОЛ.
Вот вы говорите, что компилятор встраивает тело в код, но это совершенно ничего не даёт, т.к. сам факт встраивания никак не влияет на результат работы результирующей схемы.
Можно сделать встраивание одним образом, а можно и другим.
В классическом (C, LISP) понимании, "макрос" существенно отличается от "функции" тем, что его аргументы вычисляются после подстановки самого макроса.
Например, макрос в C после подстановки внезапно может сослаться на объявленную вне макроса переменную (просто по имени), а функция (в том числе inline) так не может.
Или так:
Поэтому интересна семантика макросов, а не детали реализации компилятора.Код:#define MUL(x, y) x*y int inline mul(int x, int y) { return x * y; } ... MUL(2+2, 2); // вернёт 6, т.к. 2+2*2 (сначала подстановка макроса, а потом вычисление) mul(2+2, 2); // вернёт 8, т.к. mul(4, 2) == 4*2 == 8 (аргументы функции вычисляются до начала её работы)
Например, сейчас нигде толком не описано как происходят вычисления ОЛ схем. От входов к выходам? От выходов ко входам? Макрос вычисляется "весь целиком" или только те выходы, которые реально понадобились? Выходы вычисляются "одновременно" или только в те моменты как понадобились?
Последний раз редактировалось Владимир Ситников; 29.08.2017 в 11:13.
Расскажите, пожалуйста, в какой литературе используется такая терминология.
В C, C++, LISP, Scala понятие макроса и функции кардинально отличаются от того, что вы тут пишете.
Прежде чем жонглировать понятиями макроса-функции разберитесь с самими понятиями: https://ru.wikibooks.org/wiki/%D0%9B...BE%D1%81%D1%8B, http://alenacpp.blogspot.ru/2005/01/blog-post_28.html и т.д.
2 бага (1.9.141.11543):
Баг №1
1. Создаём макрос (2 входа, 1 выход)
2. Сохраняем проект. Исходное состояние: проект пустой, но наверху есть вкладка редактора макроса.
3. Переключаемся на редактирование макроса.
4. Нажимаем "добавить выход"
5. Переключаемся на основную схему. Важно: до переключения ничего не делать. Только переключиться
6. Сохраняем проект.
7. Добавляем макрос на полотно.
Результат: макрос добавился с одним выходом
Ожидается: должно быть 2 выхода, т.к. на шаге 4 был добавлен.
Вообще говоря, странно, что при изменении количества входов-выходов макроса требуется сохранять проект.
Баг №2
0. Берём схему, использующую макрос.
1. Добавляем выход к макросу
2. Удаляем выход у макроса
3. Сохраняем проект.
Результат: ошибка "выделенные элементы были модифицированы, требуется их заменить".
По факту же, ничего не изменилось, значит и ошибка лишняя.
Если под вмешательством подразумевается "посмотреть и одобрить", то в этом какая-то логика есть.
А вот переподключать вручную -- немного странно.
Если вы говорите про "сигнатуры функций", то напомню как в C / ST работают подобные действия. Там функцию можно вообще полностью удалить и написать заново. Если сигнатура подойдёт, то всё заработает само собой. Если же сигнатура не совпадёт (например, добавился 1 аргумент), то достаточно будет в вызывающем месте добавить этот самый аргумент и всего делов. Иными словами, изменение сигнатур не требует ходить, удалять и переписывать с нуля все места, где был вызов функции.
Проект одномоментно был сильно перекроен возникающие ошибки игнорировались, проект на симуляцию не запускался и, по-видимому, несколько ошибок наложившись друг на друга дали такой эффект.
Сейчас проявилась новая проблема, хотя ранее я ее не замечал ошибки со стеком. Сегодня загружаю V3.2 - "Внутренняя ошибка код 2 обращение к стеку". Пробую V3.1 - "Стек пуст" В версии V3 ошибок нет.
Стал удалять макросы по одному, затем нажимая отмена. Удалил макросы ErrCatch ошибка исчезла. Начал отмену ошибка не вернулась.
Заметил, что если подсвеченный красным макрос, который был изменен скопировать, а затем вставить, вставляется копия макроса неподсвеченная красным. Может быть сдесь прошел глючок?
ЗЫ: последнее обновление установил.
Последний раз редактировалось RomX; 29.08.2017 в 12:11.
Вы все конечно красиво расписали. На деле не совсем так. Нет того "умного" принятия решения о модификации макроса, о котором Вы говорите. Если Вы говорите, что пользователям нет нужды знать как компилятор обрабатывает тот или иной фрагмент схемы, то тем более зачем им тогда знать как работает анализ схемы.
С багом 1 соглашусь. При сохранении проекта изменения в макросе должны были примениться.
Про баг 2 уже сказал, что нет "умного" принятия решения. Вы описываете то, что хотели бы видеть. Таких хотелок Вы не представляете сколько у меня есть по лоджику. У меня сжатые сроки и абсолютное отсутствие человекоресурсов. Поэтому что есть, то есть.
программер
А что вы подразумевали-то под словом "inline"?
Вот тут я не соглашусь.
Вы что, предлагаете, что "надёжный программно-аппаратный комплекс ОЛ-ПР" работает "как-то автомагически"?
Приведу пример:
Чему равно y?Код:int x = 2; int y = x + x * x;
Разумеется, пользователю важно знать чего ожидать от программы. Программу же не наобум пишут, а с примерным представлением того, как она должна работать.
Так вот: y может быть равно 6, а может и 8.
При этом, ответ не зависит от того компилируется выражение в машинные коды или оно вычисляется интерпретатором.
Результат определяется именно тем, "как хотел создатель языка", а уж как реализован конкретный компилятор (на C, на Java, или ещё как) пользователей волнует в последнюю очередь.
В языках C, C#, Java и прочих явно оговорены правила вычислений выражений.
Эти самые правила никогда не ссылаются на "регистры процессора", "машинный код", "адреса памяти", ведь правила на то и правила, чтобы объяснять суть происходящего.
Вот в выражении x + x * x приоритет операции умножения выше, поэтому выражение эквивалентно выражению x+(x*x).
При этом, компилятор может хоть как это выражение вычислять.
Например, компилятор может использовать специальную инструкцию FMA (fused-multiply-add), которая за одну операцию вычислит именно это выражение.
Вот пример в случае C# (выдержка из спецификации C# 3.0):
Снимок экрана 2017-08-29 в 12.28.25.png
Так и в случае с ОЛ.
Пользователям важно знать по каким правилам должны работать схемы ОЛ.
Сказать, что "вся текущая реализация ОЛ это одно большое правило", конечно, можно, но это бесполезно.
Пользователям ОЛ важно уметь предсказывать результат программы "в уме" и без использования ОЛ. Поэтому и объяснение того, "как должны работать ОЛ схемы" (== спецификацию ОЛ языка) желательно описывать без привлечения фраз в духе "ОЛ загружает значение в стек, поэтому тут получается 2, а не 3". Да какая разница стек или регистр?
По-хорошему, должно быть более-менее стройное и простое объяснение в духе "результат работы ОЛ схемы будет неотличим от результата, полученного таким-то алгоритмом", а при этом сама программа ОЛ может использовать те оптимизации, которые удобны авторам.
PS. По-моему, вы путаете путаете понятие "спецификация" и "реализация".