Переход к препроцессору, чтобы избежать косвенного - PullRequest
0 голосов
/ 11 мая 2018

У меня есть массив структуры:

typedef struct s_values{
   field1; 
   field2;
   field3;
}t_values;

t_values values[5];

Итак, есть 5 типов, и у каждого типа есть три поля.Чтобы получить значение для определенного типа, поле должно быть получено с помощью values[type].field

Я хочу отойти от этой структуры и вместо этого использовать постоянные макросы.

Цель состоит в том, чтобы иметь макрос #define VALUE(type, field): - где тип - это перечисление, а поле - это просто имя поля

Как мне это сделать?

Я думал что-то вроде:

#define VALUE2(type, field)  type##field
#define VALUE(type, field)   VALUE2(type, field)

#define type1field1   7
#define type2field2   67
....

Но type на самом деле enum. Кроме того, я не уверен, что использование ## превосходит цель избежать косвенного обращения ..

У кого-то есть идея получше ... или помогите улучшить направление, в котором я былнаправляетесь?

1 Ответ

0 голосов
/ 11 мая 2018

Если type является постоянным значением в любое время, когда вы используете конструкцию values[type].field (единственный случай, когда вы можете надеяться заменить эту конструкцию «постоянным макросом»), то компилятор будет обращаться к ней напрямую.Кроме того, если вы пометили массив values как const, он будет знать, что нужно заменить values[type].field значением члена field из values[type], как если бы вы написали константное выражение.Любой разумный оптимизирующий компилятор сделает это бесплатно, вам не нужно загрязнять исходный код для этого.Любой разумный компилятор C должен жестко закодировать здесь значение 67 в коде f , как это делает GCC :

typedef struct s_values{
   int field1; 
   int field2;
   int field3;
}t_values;

const t_values values[5] = {7, 67};

int f(void) {
  return values[0].field2;
}

Если type не является константойзначение, когда вы используете values[type].field, тогда его нельзя заменить «постоянным макросом».Отображение из type и field должно храниться где-то, и для доступа к нему, где оно хранится, требуется косвенное обращение.В этом случае компилятор будет делать бесплатно, добавляя смещение, соответствующее field, к адресу, где хранится массив value, так что адрес для доступа вычисляется только с одним умножением и одним сложением (вместодва) во время выполнения.Опять же, это оптимально.

...