19.8.1. Битовые поля
Класс может определить (нестатическую) переменную-член как
У битового поля должны быть целочисленный тип или тип перечисления (см. раздел 19.3). Для битового поля обычно используют беззнаковый тип, поскольку поведение битового поля знакового типа зависит от реализации. Чтобы объявить член класса битовым полем, после его имени располагают двоеточие и константное выражение, указывающее количество битов:
typedef unsigned int Bit;
class File {
Bit mode: 2; //
Bit modified: 1; //
Bit prot_owner: 3; //
Bit prot_group: 3; //
Bit prot_world: 3; //
//
public:
//
//
enum modes { READ = 01, WRITE = 02, EXECUTE = 03 };
File &open(modes);
void close();
void write();
bool isRead() const;
void setWrite();
}
Битовое поле mode
имеет размер в два бита, битовое поле modified
— только один, а другие — по три бита. Битовые поля, определенные в последовательном порядке в теле класса, если это возможно, упаковываются в смежных битах того же целого числа. Таким образом достигается уплотнение хранилища. Например, пять битовых полей в приведенном выше объявлении будут сохранены в одной переменной типа unsigned int
, ассоциированной с первым битовым полем mode
. Способ упаковки битов в целое число зависит от машины.
К битовому полю не может быть применен оператор обращения к адресу (&
), поэтому не может быть никаких указателей на битовые поля классов.
К битовым полям обращаются так же, как и к другим переменным-членам класса:
void File::write() {
modified = 1;
// ...
}
void File::close() {
if (modified)
//
}
Для манипулирования битовыми полями с несколькими битами обычно используют встроенные побитовые операторы (см. раздел 4.8):
File &File::open(File::modes m) {
mode |= READ; //
// другая обработка
if (m & WRITE) //
//
return *this;
}
Классы, определяющие члены битовых полей, обычно определяют также набор встраиваемых функций-членов для проверки и установки значений битовых полей:
inline bool File::isRead() const { return mode & READ; }
inline void File::setWrite() { mode |= WRITE; }
19.8.2. Спецификатор volatile
volatile
полностью зависит от конкретной машины и может быть выяснен только в документации компилятора. При переносе на новые машины или компиляторы программы, использующие спецификатор volatile
, обычно приходится переделывать.
Программы, которым приходится работать непосредственно с аппаратными средствами, зачастую имеют элементы данных, значением которых управляют процессы, не контролируемые самой программой. Например, программа могла бы содержать переменную, значение которой изменяет системный таймер. Такой объект должен быть объявлен со спецификатором volatile
, тогда его значение может быть изменено способами, не контролируемыми или не обнаруживаемыми компилятором. Ключевое слово volatile
— это приказ компилятору не выполнять оптимизацию для таких объектов.
Спецификатор volatile
используется аналогично спецификатору const
, т.е. как дополнительный модификатор типа:
volatile int display_register; //
volatile Task *curr_task; //