Препроцессор C - взрыв массива и его длина

У меня вопрос. В моем собственном веб-сервере у меня есть следующий код в области видимости файла:

typedef struct {
    char *slice;
    int length;
} values_index;

const char *aHeaderKeys[] = {
    /* You can add here whatever you want! */
    "Accept",
    "Accept-Charset",
    "Accept-Encoding",
    "Accept-Language",
    "Authorization",
    "Expect",
    "From",
    "Host",
    "If-Match",
    "If-Modified-Since",
    "If-None-Match",
    "If-Range",
    "If-Unmodified-Since",
    "Max-Forwards",
    "Proxy-Authorization",
    "Range",
    "Referer",
    "TE",
    "User-Agent",
    "Connection"
};

int nHeadersSizes[sizeof(aHeaderKeys) / sizeof(*aHeaderKeys)];
values_index aHeaderValuesIndexes[sizeof(aHeaderKeys) / sizeof(*aHeaderKeys)];
const int nHeadersLen = sizeof(aHeaderKeys) / sizeof(*aHeaderKeys);

Но с тех пор aHeaderKeys является массивом постоянной длины константных строк, глупо вычислять длину массива во время выполнения программы, и лучше было бы написать его вручную:

typedef struct {
    char *slice;
    int length;
} values_index;

const char *aHeaderKeys[20] = {
    /* You can add here whatever you want! */
    "Accept",
    "Accept-Charset",
    "Accept-Encoding",
    "Accept-Language",
    "Authorization",
    "Expect",
    "From",
    "Host",
    "If-Match",
    "If-Modified-Since",
    "If-None-Match",
    "If-Range",
    "If-Unmodified-Since",
    "Max-Forwards",
    "Proxy-Authorization",
    "Range",
    "Referer",
    "TE",
    "User-Agent",
    "Connection"
};

int nHeadersSizes[20];
values_index aHeaderValuesIndexes[20];
const int nHeadersLen = 20;

Но количество элементов в моем массиве может меняться в процессе разработки, поэтому каждый раз, когда я хочу добавить другой элемент, мне приходится везде вручную менять длину. Теперь мой вопрос: возможно ли написать макрос препроцессора, подобный следующему, который я написал в JavaScript (как псевдокод)?

var aHeaders = [
    "Accept",
    "Accept-Charset",
    "Accept-Encoding",
    "Accept-Language",
    "Authorization",
    "Expect",
    "From",
    "Host",
    "If-Match",
    "If-Modified-Since",
    "If-None-Match",
    "If-Range",
    "If-Unmodified-Since",
    "Max-Forwards",
    "Proxy-Authorization",
    "Range",
    "Referer",
    "TE",
    "User-Agent",
    "Connection"
];

var sExplodedText = "const char *aHeaderKeys[" + aHeaders.length + "] = {\n\t\/* You can add here whatever you want! *\/\n\t\"" + aHeaders.join("\",\n\t\"") + "\"\n};\n\nint nHeadersSizes[" + aHeaders.length + "];\nvalues_index aHeaderValuesIndexes[" + aHeaders.length + "];\nconst int nHeadersLen = " + aHeaders.length + ";";

alert(sExplodedText);

2 ответа

Не нужно указывать размер массива, компилятор это выяснит. Вы можете просто сделать

const char *aHeaderKeys[] = {
...
};


#define NR_HEADERS (sizeof aHeaderKeys/sizeof aHeaderKeys[0])

Затем используйте NR_HEADERS, где вам нужно. Выражение здесь будет вычислено компилятором во время компиляции, вычисление во время выполнения не происходит.

Итак, благодаря @nos и @JonasWielicki, вот решение.

Уверен, что NR_HEADERS в следующей строке

#define NR_HEADERS (sizeof aHeaderKeys / sizeof *aHeaderKeys)

всегда будет заменен на 20 во время компиляции, и не будет вычислений во время выполнения в следующем коде:

const char *aHeaderKeys[] = {
    /* You can add here whatever you want! */
    "Accept",
    "Accept-Charset",
    "Accept-Encoding",
    "Accept-Language",
    "Authorization",
    "Expect",
    "From",
    "Host",
    "If-Match",
    "If-Modified-Since",
    "If-None-Match",
    "If-Range",
    "If-Unmodified-Since",
    "Max-Forwards",
    "Proxy-Authorization",
    "Range",
    "Referer",
    "TE",
    "User-Agent",
    "Connection"
};

#define NR_HEADERS (sizeof aHeaderKeys/sizeof sizeof *aHeaderKeys)

values_index aHeaderValuesIndexes[NR_HEADERS];
int nHeadersSizes[NR_HEADERS];

Итак, проблема решена!

Спасибо!

Другие вопросы по тегам