Вам удалось столкнуться с довольно туманным угловым падежом языка.
Выражение типа массива в большинстве случаев неявно преобразуется в указатель на первый элемент массива; Исключения составляют случаи, когда выражение является операндом унарного оператора &
, когда это операнд унарного оператора sizeof
и когда это строковый литерал в инициализаторе, используемом для инициализации объекта массива. Ни одно из этих исключений здесь не применимо.
Но в этом преобразовании есть неявное предположение: указатель на первый элемент массива object .
Большинство выражений массива - фактически, почти все из них - ссылаются на некоторый объект массива, такой как объявленная переменная массива, элемент многомерного массива и так далее. Функции не могут возвращать массивы, поэтому вы не можете получить выражение массива не-lvalue таким образом.
Но, как вы видели, функция может возвращать структуру, содержащую массив - и с выражением массива не связано ни одного объекта to_hex_string_(12345).a
.
Новый стандарт ISO C11 решает эту проблему, добавляя новую формулировку в раздел, описывающий сроки хранения. Черновик N1570 , раздел 6.2.4p8, гласит:
Не имеющее значения выражение со структурой или типом объединения, где
структура или объединение содержит член с типом массива (в том числе,
рекурсивно, члены всех содержащихся структур и союзов) относится к
объект с автоматической продолжительностью хранения и временным временем жизни .
Его время жизни начинается, когда выражение вычисляется и его начальное
значение является значением выражения. Срок его службы заканчивается, когда
оценка содержащего полного выражения или полного декларатора заканчивается.
Любая попытка изменить объект с временным временем жизни приводит к
неопределенное поведение.
В сущности, это говорит о том, что возвращаемое значение из вашей функции (в отличие от большинства результатов функции) является значением временного объекта , позволяющего распаду его члена массива дать вам (временно) допустимый указатель.
Но до тех пор, пока компиляторы полностью не поддержат новый стандарт C (который не будет в течение нескольких лет), вам просто нужно будет избегать обращения к членам массива возвращаемых структур.