В выражении присваивания должно быть место для хранения присваиваемого значения. Таким образом, левый операнд должен обозначать такое место. Это называется lvalue - lvalue - это выражение, которое обозначает объект, такой как int
, double
, другой тип basi c, структура и некоторые другие вещи.
Самым распространенным lvalue является просто идентификатор - имя объекта. Например, после int x;
определяет объект (память, зарезервированная для x
) и идентификатор (имя x
), x
обозначает объект.
Константы, такие как 37
или 'a'
- это просто значения в C. Они ничего не обозначают в памяти. Большинство выражений производят простые значения, а не lvalues. Например, результат 3 * x
в три раза превышает значение x
(если переполнения нет), и это просто значение, а не lvalue, даже если в нем используется x
. Другой пример - результат приведения (char *) p
- это просто значение указателя; это не lvalue для p
.
Другие lvalue включают в себя:
Результаты применения унарных *
к указателям. Если p
является указателем с допустимым значением, указывающим на некоторый объект, тогда *p
является lvalue для объекта, поэтому вы можете написать *p = 37;
, предполагая, что тип объекта совместим с назначенным 37.
Члены структур. Если s
является структурой с членом foo
, тогда s.foo
является lvalue для этого члена. Это относится и к указателям на структуры; если p
указывает на s
, тогда p->foo
является lvalue для члена foo
. (Обратите внимание, что s
само по себе должно быть lvalue. Возможно иметь временную структуру, которая является просто значением. В этом случае ссылка на его член является просто значением, а не lvalue.)
В назначении (char *)fh += flen + SIZEOF_HL_DATA_HDR
, (char *)fh
не определено как lvalue по стандарту C. Если этот код был принят неким C компилятором, то этому компилятору было предоставлено необычное расширение для языка C.
Похоже, целью этого оператора является добавление flen + SIZEOF_HL_DATA_HDR
байтов к указанному месту до fh
. Если это так, это может быть достигнуто путем преобразования fh
в char *
, добавления требуемой суммы, преобразования обратно в тип fh
, а затем присвоения результата fh
:
fh = (struct hl_filelist_hdr *) ((char *) fh + flen + SIZEOF_HL_DATA_HDR)
(Существуют определенные опасности при выполнении такого рода арифметики необработанных указателей c. Этот ответ не говорит с ними; мы предполагаем, что базовый код имеет дело с ними и предназначен для реализации, поддерживающей то, что он делает.)