Задача: нужно написать некоторый макрос TICK(x), который бы при каждом вызове увеличивал переменную x на константу TO_TICK, но с учетом переполнения. Т.е. в случае если добавление TO_TICK вызовет переполнение, переменную x не изменять. Тип переменной x может быть любой целый (в том числе битовое поле).
Вариант 1:
Код
#define TICK(x) do{if((x + TO_TICK) > x) x += TO_TICK;}while(0)
не помогает, в случае знакового x и беззнакового TO_TICK. Видимо, (x + TO_TICK) считается беззнаковым и сравнивается с беззнаковым x.
Вариант 2:
Код
#define TICK2(x) do{typedef typeof(x) _tx; _tx _x = x; _x += TO_TICK; if(_x > x) x = _x;}while(0)
в принципе устраивает, но не работает с битовыми полями.
Параллельно узнал, что char без указания знаковости в "gcc version 4.8.0 20121121 (experimental) (Klen's GNU package (KGP) for ARM/elf platform)" является unsigned, хотя везде указывается диапазон char от -128 до 127. В "gcc версия 4.4.3 (GCC)" под Linux char знаковый.
Где нужно читать о типах данных C/GCC и приведении типов в арифметических операциях и операциях сравнения?
Кстати, при различных уровнях оптимизации результат тоже получаю различный. Хочется большей строгости...
Спасет ли переход на C++/GCC ?