Подтвердить что ты не робот

Какова цель массива нулевой длины в структуре?

Когда я смотрю код ядра Linux, вы обнаружите код ниже:

   struct thread_info {
    struct task_struct  *task;
    struct exec_domain  *exec_domain;
    unsigned long       flags;
    __u32           status;
    __u32           cpu;
    int         preempt_count;
    mm_segment_t        addr_limit;
    struct restart_block    restart_block;
    void __user     *sysenter_return;
    unsigned long           previous_esp;
    __u8            supervisor_stack[0];
};

Обратите внимание, что последняя переменная "supervisor_stack", это массив с нулевой длиной, каково его использование? Спасибо заранее!

4b9b3361

Ответ 1

Это пред-C99-версия гибкого элемента массива, предлагаемого GCC в качестве расширения.

Путь C99 - это определение элемента гибкого массива с пустыми скобками,

__u8  supervisor_stack[];

Он используется для хранения данных, количество которых не является постоянным, связанным с структурой. Память выделяется в форме

struct foo *ptr = malloc(sizeof *ptr + whatever_is_needed);

В пункте 18 раздела 6.7.2.1 стандарт (проект N1570) описывает их:

В качестве особого случая последний элемент структуры с более чем одним именованным элементом может имеют неполный тип массива; это называется гибким элементом массива. В большинстве ситуаций, гибкий элемент массива игнорируется. В частности, размер структуры выглядит так, как если бы гибкий элемент массива был исключен, за исключением того, что он может иметь более длинное дополнение, чем упущение будет означать. Однако, когда оператор . (или ->) имеет левый операнд, который равен (указатель на) структуру с гибким членом массива и именами правых операндов, которые член, он ведет себя так, как если бы этот элемент был заменен самым длинным массивом (с тем же тип элемента), который не сделает структуру больше, чем объект, к которому обращаются; смещение массива должно оставаться равным элементу гибкого массива, даже если это будет отличаться от матрицы замены. Если этот массив не будет содержать никаких элементов, он будет вести себя так, как будто он имел один элемент, но поведение undefined, если предпринимаются попытки получить доступ к этому элемент или создать указатель, который проходит мимо него.

Ответ 2

Это обычный C-хак, чтобы объявить то, что можно назвать переменным length-array (где вы определяете размер при времени размещения

Пример:

struct line {
   int length;
   char contents[0];
 };

 struct line *thisline = (struct line *)
   malloc (sizeof (struct line) + this_length);
 thisline->length = this_length;

Таким образом, у вас есть структурное определение ваших данных, которое также сохраняет длину массива для очевидных целей согласования, но вы не ограничены фиксированным размером, который обычно ассоциируется со структурой

Пример, взятый из здесь (также более подробная информация там)