В обоих определениях не говорится, что "байт" является минимальной адресуемой единицей.
Это потому, что им это не нужно. Байтовые типы (char
, unsigned char
, std::byte
и т. Д. c) имеют достаточные ограничения, обеспечивающие соблюдение этого требования.
Размер побайтных типов явно определен для быть точно 1 :
sizeof (char), sizeof (char со знаком) и sizeof (char без знака) равны 1.
Выравнивание побайтово типы - наименьшее возможное выравнивание :
Кроме того, узкие типы символов (6.9.1) должны иметь самое слабое требование выравнивания
Это не Конечно, выравнивание не должно быть равным 1. За исключением ... это так.
Видите, если бы выравнивание было больше 1, это означало бы, что простой байтовый массив не работал бы. Индексирование массива основано на арифметике указателя c, а арифметика указателя c определяет следующий адрес на основе sizeof(T)
. Но если alignof(T)
больше sizeof(T)
, то второй элемент в любом массиве T
будет смещен. Это недопустимо.
Поэтому, хотя в стандарте прямо не указано, что выравнивание байтовых типов равно 1, другие требования гарантируют, что оно должно быть.
В целом это означает, что каждый указатель к объекту имеет выравнивание, по крайней мере, такое же ограничительное, как и для байтового типа. Таким образом, указатель объекта не может быть смещен относительно выравнивания побайтовых типов. Поэтому все действительные указатели, отличные от NULL (указатели на активный объект или указатель конца-в-конце) должны быть как минимум выровнены настолько, чтобы указывать на char
.
Аналогично, разница между двумя указатели определены в C ++ как разница между индексами массивов элементов, на которые указывают эти указатели (арифметика указателей c в C ++ требует, чтобы два указателя указывали на один и тот же массив). Арифметическое указателя аддитива c соответствует указанному ранее на основе sizeof
типа, на который указывает тип.
Учитывая все эти факты, даже если в реализации есть указатели, адреса которых могут адресовать значения, меньшие char
, функционально невозможно для абстрактной модели C ++ сгенерировать указатель и при этом иметь счетчик указателей как действительный (указывающий на объект / функцию, конец массива или значение NULL) , Вы можете создать такое значение указателя с помощью приведения из целого числа. Но вы бы создали недопустимое значение указателя.
Таким образом, хотя технически на машине могут быть меньшие адреса, вы никогда не сможете использовать их в действительной, правильно сформированной программе C ++.
Очевидно, что расширения компилятора могут делать все что угодно. Но что касается соответствующих программ, просто невозможно создать действительные указатели, которые выровнены для побайтовых типов.