Инициализировать указатель внутри структуры эффективно в C - PullRequest
1 голос
/ 20 декабря 2011

Как я буду эффективно инициализировать следующую структуру данных (не затрачивая никаких вычислений)?Он состоит из массива struct Register .Длина массива, на который указывает FieldArrayPointer каждого struct Register , будет разной. Как извлечь указатель (используя директиву компилятора?) И использовать его для инициализации массива struct Register?Есть ли альтернативный способ создания структуры данных, как это (я не хочу использовать связанный список)?(N может быть сколь угодно большим)

    struct Field
    {
        char    High;                
        char    Low;                
        char    Attribute;
    } FieldArray[L0+L1+L2...+L(N-1)];

    struct Register 
    {
       unsigned int    ResetValue;
       unsigned int    FieldArrayLength;
       struct Field    *FieldArrayPointer;
    } RegisterArray[N] =

    { ResetValue0,     L0,    <Pointer of FieldArray[0].Field>,
      ResetValue1,     L1,    <Pointer of FieldArray[L0].Field>,
      ResetValue2,     L2,    <Pointer of FieldArray[L0+L1].Field>,
      . . . . . . . . . . . . . . . . . . . . . . . . . . . . ,
      ResetValue(N-1), L(N-1),<Pointer of FieldArray[L0+L1+..+L(N-2)].Field>
    };

   //L0,L1,L2.. and N are constant integers

Ответы [ 2 ]

1 голос
/ 20 декабря 2011

Полагаю, вы обеспокоены тем, что для вычисления L0 + L1 + L2 и т. Д. Требуется время.

Если L0, L1 и т. Д. Являются константами, и, как вы упомянули, сценарий perl генерирует код с этими значениями, любой компилятор с достойной оптимизацией будет предварительно вычислять эти значения.

Это называется постоянным распространением: http://en.wikipedia.org/wiki/Constant_folding

gcc может сделать это, например:

Вот фрагмент кода, который я написал:

char fubar[100];

struct bar
{
  char *ptr;
  int length;
} array[3] =
{
  {fubar, 10},
  {fubar+10, 20},
  {fubar+10+20, 70}
};

Вот что сгенерировал 'gcc -O2':

.globl array
    .data
    .align 4
    .type   array, @object
    .size   array, 24
array:
    .long   fubar
    .long   10
    .long   fubar+10
    .long   20
    .long   fubar+30
    .long   70
    .comm   fubar,100,32
    .ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3"
    .section        .note.GNU-stack,"",@progbits

Сгенерированный код не вычисляет смещения каждый раз.

1 голос
/ 20 декабря 2011

Предполагая, что FieldArray имеет статическую длительность хранения и от L0 до Ln являются целочисленными константными выражениями, вы можете просто сделать:

struct Register 
 {
    unsigned int    ResetValue;
    unsigned int    FieldArrayLength;
    struct Field    *FieldArrayPointer;
 } RegisterArray[N] =
 { 
   { ResetValue0,     L0,    FieldArray + 0 },
   { ResetValue1,     L1,    FieldArray + L0 },
   { ResetValue2,     L2,    FieldArray + L0 + L1 },
   ...
 };

Если выписать это вручную слишком громоздко, вымог бы написать генератор кода для создания источника и #include результата.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...