2014-01-29 6 views
5

Мне было интересно, если бы C имела функциональность в языке или компиляторе (gcc), чтобы я мог превратить свой int intizedized array в таблицу поиска времени comp const. Вот реконструируют моей ситуации:Таблица поиска времени компиляции в C (C11)

typedef struct Entry { 
    bool alive; 
    float a, b, c; 
    double d, e, f; 
} Entry; 

Теперь у меня есть объявление для массива:

extern const int entryCount; // Assume this is equal to an enum value. 
extern const Entry entries[entryCount]; 

Как указывалось выше, позиция в массиве по сравнению с константой перечислений, что характерно данные помещаются в структуру ввода. Предположим, что entryCount инициализируется количеством записей в перечислении. Вот где мой вопрос, когда я инициализировать этот массив следующим образом:

const int entryCount = ENTRY_COUNT; 
const Entry entries[entryCount] = { 
    { false, 0.1f, 0.2f, 0.0f, 1.0, 1.0, -1.0 }, 
    ... 
}; 

Создаются они во время компиляции и не создают накладные расходы во время выполнения? Или он выделяется в памяти во время выполнения? Потому что значения никогда не изменятся. Как я могу достичь этого в C?

ответ

3

Вы можете достичь того, чего хотите, если все компоненты, необходимые для определения вашего массива, являются константами времени компиляции в смысле стандарта C. Единственное, что вы не дали, это entryCount. Это действительно должно быть enum постоянным.

Тогда вам нужно будет поместить этот массив в глобальный массив (область файлов). Если вы хотите включить один и тот же массив через файл include (.h) в разные .c-файлы (так называемые единицы компиляции), вам придется объявить его static, чтобы несколько определений не конфликтуют при связывании программы ,

enum { entryCount = ENTRY_COUNT }; 
static const Entry entries[entryCount] = { 
    { false, 0.1f, 0.2f, 0.0f, 1.0, 1.0, -1.0 }, 
    ... 
}; 

static здесь означает, что это создает переменную, которая имеет срок службы, которая охватывает всю выполнение программы, но это не внешний символ для этой переменной не генерируется. Это необходимо, если вы используете #include одно и то же определение переменной в несколько файлов .c.

У этого нет служебных данных во время работы, и доступ к записи, такой как entries[4].d, должен теперь оптимизироваться хорошим оптимизирующим компилятором.

У этого есть только один недостаток, поскольку он дублирует генерацию массива во всех единицах, даже если он не нужен. Один из способов избежать этого будет макрос, который расширяется к соединению буквальным как этот

#define ENTRIES (const Entry [entryCount]){  \ 
    { false, 0.1f, 0.2f, 0.0f, 1.0, 1.0, -1.0 }, \ 
    ...           \ 
} 

The const, чем оставляет свободу действий для компилятора выделить этот массив только один раз (если таковые имеются) и позволит избежать дополнительной копии в компиляции которые не используют эту функцию вообще.

+0

Для уточнения, я предполагаю, что вы имеете в виду «если вы хотите скопировать/вставить тот же самый код объявления массива в несколько разных файлов c, он должен быть статическим»? Потому что, очевидно, вы не можете получить доступ к одной и той же переменной массива из разных файлов в случае, если это 'static'. Кроме того, на самом деле нет никакого вреда для создания постоянной глобальной и доступной из нескольких файлов. Константы не могут использоваться для создания кода спагетти.Но, конечно, вы получили бы еще одно имя в глобальном пространстве имен (что, скорее всего, не было biggie). – Lundin

+0

Благодарим вас за быстрый ответ. Я довольно новичок в языке C, и, исходя из фона C++, «статический» немного отличается по смыслу от того, что я знаю. Я полагал, что статичность в C означает, что она доступна только в текущем блоке компиляции, это неправильно? –

+0

@StevenFloyd Правильно, вы читали ответ так же, как я. :) В ожидании разъяснения от Йенса до того, как я перевежу. – Lundin

0

Вы можете определить массив глобально один раз (в .c файле, наверное) и объявить его несколько раз (в какой-то файл .h включен везде). То, что это const, не имеет никакого значения. Он будет выделен один раз при компиляции/загрузке в память.

 Смежные вопросы

  • Нет связанных вопросов^_^