Какой тип я должен использовать для числа бит в фундаментальном типе? - PullRequest
0 голосов
/ 11 декабря 2018

Основные типы в C ++ имеют размеры от 1 до 8 (возможно, 16) в 64-разрядных операционных системах.Это означает, что число битов, которые они занимают в памяти, не превышает 128, то есть количество битов вписывается в uint8_t.

Теперь, предположим, я пишу некоторую функцию, которая принимает такое количество бит.Например, предположим, что это

template <typename T>
inline void clear_bit(T& x, magic_type bit_index ) {
    static_assert(std::is_fundamental_v<T>, "Go away.");
    x = x & ~(T{1} << bit_index);
}

Мне интересно, что использовать для magic_type: это должен быть uint8_t?Или, может быть, это просто int, поскольку мне все равно нужно проверять правильность, даже для случая uint8_t, а int является более "естественным" типом для чисел?

Toуменьшите этот вопрос в отношении вашего индивидуального мнения: один из вариантов обычно считается более идиоматическим?Если нет, можете ли вы найти достаточно веские причины для обоих вариантов?Или, может быть, предложить третий?

1 Ответ

0 голосов
/ 11 декабря 2018

Какой бы тип вы не использовали для bit_index в выражении T{1} << bit_index, он будет повышен до int или unsigned int в любом случае, а результат T{1} << bit_index сам по себе является повышенным типом T{1}.Это означает, что x & ~(T{1} << bit_index) всегда дает тип, который по крайней мере «столь же велик», как и int.

Выражение T{1} << bit_index четко определено, только если
bit_index >= 0 && bit_index < (sizeof +T{}) * CHAR_BIT).Последующее присваивание x может все еще усечь результат.

Как правило, если вы собираетесь использовать переменную в арифметических выражениях, используйте int или unsigned int.unsigned обычно предпочтительнее в побитовых арифметических контекстах, в противном случае просто используйте signed.

Нижняя строка : используйте unsigned int или, возможно, signed int.

...