fk0, легенда (04.05.2018 14:24, просмотров: 497) ответил Vit на А что там с uint_fast8_t в логических выражениях? Есть "обрезание" до 8 бит в логических выражениях? Слыхал, что вроде как есть, но ни разу не проверял (ни разу не было явной необходимости использовать). Если есть, то получается, компилятор должен
Ко всем вычислениям применяется правило integer promotion. Заключающееся в расширении до размера int всех типов меньших размеров перед началом вычисления. Поэтому что uint_fast8_t, что unsigned char, если размер uint_fast8_t меньше инта, оба расширяются до инта, и дальше вычисляется. Но если uint_fast8_t 32-битный например (на ARM/MIPS), то понятно, вычисляется как есть (впрочем он и так равен инту).
А вот расширение до инта для знаковых и беззнаковых проходит по разному. Для первых знаковый бит копируется во все старшие биты, для беззнаковых старшие биты заполняются нулями. Здесь можно реально нарваться. И, кстати, здорово нарваться можно на знаке char-типа. Если с unsigned char и signed char всё понятно, то просто char он в разных компиляторах то знаковый, то беззнаковый (бывает вообще опцией компилятора задаётся). Поэтому при арифметике над просто char следует всегда насильно задавать старшие биты при расширении до инта (например: x = c & 0xFF).
Ещё надо сказать про алгебру. В языке C для беззнаковых типов получается, что выражения, например, "a - b < c" и "a < c + b" не являются эквиэвалентными. Потому, что если в первом в левой части получается отрицательный результат, то для беззнаковых это переполнение и в общем не верный результат. А алгебраически выражения эквиэвалентны. И поэтому когда программист пишет код он может не подумать и написать первое выражение вместо второго и получить ошибку.
[ZX]