Гарантирует ли sizeof(T) * CHAR_BIT размер в битах?

Похоже, что нет какой-либо библиотечной функции для вычисления размера типа в битах.

Правильно ли я предполагаю, что это можно сделать следующим образом?

#include <climits>

template <typename T>
size_t Size_In_Bits(){
    return sizeof(T) * CHAR_BIT;
}

Будет ли это всегда возвращать количество битов, которое может быть нацелено на тип?


person Trevor Hickey    schedule 08.03.2016    source источник
comment
Что такое бит, который может быть нацелен на тип?   -  person user253751    schedule 09.03.2016
comment
@chux Я изменил тег C на C++. Хотя, я хотел бы знать, есть ли различия между языками. Вышеупомянутая реализация могла бы вместо этого быть макросом C с limit.h   -  person Trevor Hickey    schedule 09.03.2016
comment
Уверен, что между C/C++ нет разницы в размерах.   -  person chux - Reinstate Monica    schedule 09.03.2016
comment
@immibis Да, я полагаю, это вводит в заблуждение. Количество битов, которые физически хранятся в памяти и могут быть изменены с помощью битовых манипуляций.   -  person Trevor Hickey    schedule 09.03.2016


Ответы (2)


Это гарантированно даст вам размер (хранилище) в битах, но не ширину (количество битов значения). Последнее может быть меньше, если тип имеет биты заполнения. Для типов без знака вы можете измерить количество битов значения напрямую, преобразовав -1 в тип (чтобы получить максимально возможное значение в типе) и подсчитав их. Для подписанных типов можно использовать std::numeric_limits<T>::max(), чтобы получить макс. Или, если вы уже знаете конкретный тип, вы можете использовать макросы xxx_MAX из limits.h или stdint.h.

person R.. GitHub STOP HELPING ICE    schedule 08.03.2016
comment
Хороший ответ о преобразовании (без знака) -1 в тип и их подсчете, а также о невозможности измерить количество битов значения в подписанном типе. - person chux - Reinstate Monica; 09.03.2016
comment
если вы знаете, какой это тип - или вы можете использовать std::numeric_limits<T>::max() - person user253751; 09.03.2016
comment
О, извините, вопрос был помечен как C++, а не C. В таком случае мой ответ несколько неверен... - person R.. GitHub STOP HELPING ICE; 09.03.2016
comment
Внесены некоторые изменения; надеюсь сейчас лучше. - person R.. GitHub STOP HELPING ICE; 09.03.2016
comment
@R .. Я думал, что недополнение было неопределенным поведением? Или это отличается, когда вы инициализируете и не подписываете с отрицательным значением 1? - person Trevor Hickey; 09.03.2016
comment
@TrevorHickey: недополнения не происходит. Целочисленные преобразования в беззнаковые типы четко определены и выполняются как редукция по модулю TYPE_MAX+1. - person R.. GitHub STOP HELPING ICE; 09.03.2016

sizeof(T) * CHAR_BIT возвращает количество битов, которые тип занимает в памяти.

Тем не менее, размер битов может быть больше, чем биты, которые математически могут быть использованы целым числом (рассмотрите биты заполнения).


Подробности: целые числа имеют биты значения, бит знака (целые числа со знаком) и возможные биты заполнения. Все эти биты влияют на размер хранилища.

unsigned char никогда не будет битов заполнения.

person chux - Reinstate Monica    schedule 08.03.2016
comment
Называть это дополнением крайне неправильно. Заполнение означает что-то еще в C и C++. - person Lightness Races in Orbit; 09.03.2016
comment
@BarryTheHatchet Спецификация C §6.2.6.2 2 называет дополнительные биты битами заполнения. Используемое здесь заполнение не вводит в заблуждение в C и C++, поскольку оно используется в двух контекстах: биты, как упоминалось здесь, и байты заполнения структур. Ответ переработан, чтобы называть их битами заполнения, чтобы их можно было отличить от байтов заполнения. IAC, это по-прежнему форма padding согласно спецификации языка. - person chux - Reinstate Monica; 09.03.2016
comment
Возможно, спецификация C делает это, но спецификация C++ - нет (по модулю единственного, потерянного упоминания в ненормативном тексте в §29.6.5, относящемся к поведению memcpy). Однако биты заполнения все еще достаточно устраняют неоднозначность, поэтому спасибо за добавление второго слова. - person Lightness Races in Orbit; 09.03.2016
comment
@BarryTheHatchet Обратите внимание, что во время этого ответа сообщение было помечено как [C], а не [C++]. OP неоднозначно относился к C/C++, но использовал C++ template, а позже изменил тег с C на C++. - person chux - Reinstate Monica; 09.03.2016