Circiter писал(а):
Просветите, если не сложно, ok? Спасибо.
Не сложно, но Вы ведь и сами все понимаете.
Circiter писал(а):
Простите, но получился диалог в духе: -- Черное или белое? -- Да.
Т.е. именно выравнивание может кушать лишние байты?
И выравнивание, и то, что тип char может занимать больше, чем 1 байт (8 бит).
Например, на 16-битных DSP-процессорах фирмы Texas Instruments, основанных на ядре TMS320 минимально адресуемое кол-во памяти - 16 бит, и его родной компилятор СИ хранит char в 16 битах, и sizeof(char) = sizeof(int) = 1.
Circiter писал(а):
И опять я не понял... На любых ведь машинах статично распределенные строки обычно хранятся с исполняемым образом на энергонезависимом носителе (хард, флеш, неважно), а потом копируются (или лучше сказать, отображаются) в оперативную память.
А чем Вам Flash не память? Да и пространство на HDD не бесконечно. И именно, что копируются. Отображать в ОЗУ адреса с flash технически сложно - flash массив обычно читается целыми большими секторами (64 килослова и т.п.), а HDD слишком медленный - не имеет смысла.
Circiter писал(а):
Почему? На 16-ти разрядных компах указатели два байта весят, на 32-х разрядных -- 4 байта. В том примере с индексированием строки оптимизатор вроде-бы не обязан игнорировать арифметику указателей, и, возможно, даже указатель будет храниться именно в ОЗУ (а не в регистре или в CPU-инструкции чтения, используемой для доступа к строке).
Да указатели тут непричем. Там идет просто константный массив последовательно расположенных объектов типа char, не имеющий даже собственного имени. Для этого не требуется использовать арифметику указателей, косвенная адресация на него будет уже в процессе выполнения кода, с использованием регистров процессора (если программа может динамически размещаться в памяти, т.е. "exe"; если программа со статическим размещением, то там вообще будет присутствовать абсолютный адрес этогой строки и все - программа типа "com").
-- Пн сен 28, 2009 08:55:20 --PapaKarlo писал(а):
Все это, разумеется, так, только есть одно "но". Реальный код, генерируемый компилятором, учитывает тип элементов массива - именно массива, и в этом уже нет никакой симметрии. В результате конструкция *( ( <выражение1> ) + ( <выражение2> ) ) отражает не всю правду: то выражение, которое является не адресом массива, на самом деле умножается на sizeof(array[0]). Попробуйте использовать вместо идентификатора массива void* и посмотреть, что скажет компилятор. Или преобразовать оба выражения 1 и 2 к целому...
Извините, может быть потому, что сейчас утро понедельника, но никак не вникну, что Вы хотите сказать и в чем, по Вашему, заковыка.
И в случае индексации массива, и в случае операции сложения указателя определенного типа с целым, выполняется умножение на sizeof(array[0]). В чем проблема-то?
Использовать же в качестве типа элементов массива void естественно нельзя. Используя какой-нибудь второй указатель типа void * на заренее объявленный массив возможно, но для его индексации Вы вынуждены будете сами приводить его к какому-нибудь осмысленному типу. Приведя его к типу, отличному от типа элементов нашего массивы, Вы получите ерунду, когда размеры типов не совпадают. Другое дело, что обсуждалось то несколько иное.