Перейти к содержанию
    

Макрос инкремента с насыщением.

А вам точно нужно это? Может, лучше - с ограничением?

#define VAR_INC(x, step, max) x = ((x + step)>max)? max : (x + step)

Не пойдет(

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

Хотелось на автомате...

Но за неумением "объяснить" свои намеренья оптимизирующему компилятору придется вводить единый тип для всех "тикалок".

Кста, Ваша идея мне нравится и везде я стараюсь пользоваться конструкциями

 

TICK(timeout);
if(timeout >= TO_TIMEOUT)
{
  state = NEW_STATE;
  timeout = 0;
}

 

или

 

if(timeout < TO_TIMEOUT) TICK(timeout);

 

Что так или иначе ограничивает увеличение timeout, но второй вариант можно использовать только если ограничение какое-то одно (фиксированное), а сам таймер предназначен для ожидания какого-то одного события. Если это не так, то использую вариант 1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

не помогает, в случае знакового x и беззнакового TO_TICK. Видимо, (x + TO_TICK) считается беззнаковым и сравнивается с беззнаковым x.
Конечно, если TO_TICK явно беззнаковое, то в (x + TO_TICK) сначала будет приведение x к беззнаковому.

А зачем TO_TICK беззнаковое? Оно же явно должно влазить по диапазону в знаковые числа, а при (unsignedX + signedTICK) уже тик приведётся к беззнаковому и будет все нормально.

Хотя с битовыми полями и прочими заужениями до байтов все равно будет плохо, так как в + сначала обе стороны приведутся к int и для uint8_t всё равно всегда ((255+1) > 255) истинно и прибавление тика не остановится.

 

Кстати, с typeof можно и проще

#define TICK(x) do { if ( (typeof(x))(x+TO_TICK) > x ) x += TO_TICK;}while(0)

но с битовыми полями так же не будет работать. Хотя я в таких местах ниже байта не опускаюсь, битовые поля - счётчики немного экономят ОЗУ, но раздувают код (Cortex-M3-шные команді работы с битовыми полями штука хорошая, но не везде есть).

 

И лучше уж C++ шаблонную функцию, чем такой макрос. Не вижу препятствий работать в процедурном стиле даже без простейших классов, но с такого рода шаблонами. А для кого есть gcc, для того есть и g++.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Конечно, если TO_TICK явно беззнаковое, то в (x + TO_TICK) сначала будет приведение x к беззнаковому.

А зачем TO_TICK беззнаковое? Оно же явно должно влазить по диапазону в знаковые числа, а при (unsignedX + signedTICK) уже тик приведётся к беззнаковому и будет все нормально.

Я-то боюсь, что "умный" оптимизатор вообще вправе выкинуть финт: если к некоторому числу прибавить положительную константу, то результат (чисто в математическом смысле) будет БОЛЬШЕ исходного числа - поэтому условие всегда истинное. А если программисту нужна такая "платформенная вещь" как "переполнение", то либо врукопашную оптимизируй, либо научись грамотно указать оптимизатору свои намеренья.

 

Вывод для себя делаю такой: если переполняется какая-то переменная, то алгоритм можно считать плохим. На этапе проектирования не нужно допускать неограниченного инкремента "тикающих" переменных (справедливо для всех случаев, кроме измерителя uptime, но тут нужно наращивать разрядность, либо вводить масштаб).

 

Для битовых полей написать специальный макрос/функцию для выполнения этой конкретной задачи.

 

Вообще, это скорее проблема программиста (моя), а не инструмента: хочется чтобы программа сама себя писала, но для решения данной проблемы есть ДРУГИЕ инструменты, которыми и нужно пользоваться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я-то боюсь, что "умный" оптимизатор вообще вправе выкинуть финт: если к некоторому числу прибавить положительную константу, то результат (чисто в математическом смысле) будет БОЛЬШЕ исходного числа - поэтому условие всегда истинное.

Зря боитесь, не будет такого. Компилятор всё делает по стандарту языка Си (с точностью до глюков компилятора, но мы же не о них сейчас говорим). В стандарте четко прописана семантика переполнения целочисленной переменной.

 

Вообще, это скорее проблема программиста (моя), а не инструмента: хочется чтобы программа сама себя писала, но для решения данной проблемы есть ДРУГИЕ инструменты, которыми и нужно пользоваться.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне интересно другое. А насыщение в виде равенства нулю? Зачем инкремент, если можно декремент?

Шаманобубен какой-то...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...