Инициализация статического массива из константной строки - PullRequest
2 голосов
/ 13 сентября 2011

Я занимаюсь программированием низкого уровня.Для цели моей задачи мне нужно инициализировать (иногда аппаратно ограниченный) массив.Это может быть просто char [], но также unsigned short или что-то в этом роде.

Наиболее читаемый способ - использовать просто некоторую строку постоянной известной длины.Чтобы облегчить задачу, я написал макрос, чтобы помочь себе.

#define INI( x ) { (x[0] << 8) | 0x00, (x[1] << 8) | 0x00 }

static const unsigned int tab[] = INI("ab");

int main(){
    return 0;
}

Конечно, макрос выше находится внутри некоторого блока #ifdef и зависит от архитектуры, на которой он построен.У меня проблема в том, что я получаю ошибку:

initializer element is not constant
main.c:3: error: (near initialization for "tab[0]")
initializer element is not constant
main.c:3: error: (near initialization for "tab[1]")

Но приведенный выше код расширяется до:

static const unsigned int tab[] = { ("ab"[0] << 8) | 0x00, ("ab"[1] << 8) | 0x00 };


int main(){
    return 0;
}

Каждый и КАЖДЫЙ элемент не только постоянны во время компиляции, но иво время препроцессора.Можно было бы даже создать макрос, берущий каждый символ из строки и выполняющий некоторые манипуляции (если бы только препроцессор мог получить длину строки и, конечно, имел бы некоторую возможность зацикливания).

Итак - почемуКомпилятор не может извлечь эту информацию, и каковы мои варианты?Любая помощь искренне ценится.

PS.Я знаю, что он работает внутри main () как

const unsigned int tab[] = INI("ab");

, но мне это нужно вне любой функции.

Ответы [ 2 ]

1 голос
/ 13 сентября 2011

Вы не можете выполнять индексирование / индексацию строк в препроцессоре. Что вы можете сделать, это немного изменить макрос:

#define ROW( x, y ) { ((x) << 8) | 0x00, ((y) << 8) | 0x00 }

static const unsigned int tab[] = ROW('a' , 'b');
0 голосов
/ 13 сентября 2011

При условии, что это C99, стандарт гласит:

Выражения в этом составном литерале должны быть постоянными.

в отношении примера указателя с областью действия файла. Вам недостаточно иметь выражение с постоянными переменными - оказывается, что выражение (я) также должно быть постоянным.

...