C # определение оператора, перечисление, структура - PullRequest
1 голос
/ 26 января 2012

У меня есть устаревший код, который содержит этот typedef:

typedef enum simple_op_enum {
    #define SOP(OPCODE, NAME, FORM, SUIFOP) OPCODE ,
    #include "simple_ops.def"
    LAST_OP
} simple_op;

Файл #include содержит несколько строк вида:

/*  no operand instructions */
SOP( NOP_OP,    "nop ",     BASE_FORM,  io_nop)

Токен "simple_op" встречается позже в структуре:

typedef struct simple_instr_struct {
    simple_op opcode;           /* the opcode */

Есть несколько вещей, которые я не понимаю:

  1. Что достигается при наличии запятой в конце оператора #define? Я думал, что это незаконно.

  2. Что достигается перечислением, особенно LAST_OP

  3. Как получить доступ к значению кода операции в simple_instr_struct?

Ответы [ 5 ]

1 голос
/ 26 января 2012

Если вы сомневаетесь в макросах, вы всегда можете использовать препроцессор, чтобы увидеть, как они расширяются:

gcc -E file.c -o file.txt

Вывод будет большим, если в нем много заголовочных файлов, но где-то вы найдете там свои макросы - возможно, ближе к концу

1 голос
/ 26 января 2012
  1. Это не незаконно, это часть того, что препроцессор заменит все экземпляры SOP(x, y, z) на.

  2. Создает перечисление с содержимым в simple_ops.def.Поскольку содержимое этого файла SOP(w, x, y, z), все они превратятся в w, а enum будет:

typedef enum simple_op_enum {
   NOP_OP , // <- notice the space before the comma, like the #define does
   ...      // the others
   LAST_OP
} simple_op;

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

Эта вещь #include является хитрым трюком, так чтовсе определения могут быть в одном месте (файл), а код, который #include s, он просто определяет, SOP - это то, что ему нужно.Затем изменение этого одного файла повлияет на весь код, который нуждается в нем, и код использует их так, как ему нужно.Например, для некоторого кода может потребоваться только имя, поэтому для извлечения имени будет определено SOP как #define SOP(w, x, y, z) x.

3) Вы можете получить к нему доступ, выполнив simple_instr_struct_instance.opcode

0 голосов
/ 26 января 2012

Запятая в конце #define допустима.это часть макроса.константы перечислений разделяются запятой, и этот макрос беспокоится об этом.

enum - это просто переменная, которая может содержать любое из значений, указанных вами в объявлении перечисления.так как они переведены в числа, LAST_OP будет равен числу возможностей.

Вы можете получить доступ к члену, как:

struct simple_instr_struct a;
a.opcode=LAST_OP;
0 голосов
/ 26 января 2012
  1. Запятая является лишь частью замены текста, которая будет происходить при использовании макроса.В этом случае добавляется запятая после каждого кода операции, так что список будет иметь правильный синтаксис enum.

  2. Результат #define и #include являетсяперечисление, которое выглядит следующим образом:

    typedef enum simple_op_enum {
      NOP_OP,
      .
      .
      .
      LAST_OP
    } simple_op;
    

    То же самое можно увидеть, посмотрев выходные данные запуска вашего исходного кода через препроцессор Си.LAST_OP - это только последняя запись в вашем новом перечислении.

  3. Вам необходимо определить переменную этого типа:

    struct simple_instr_struct myStruct;
    

    и затем получить доступ кПоле, о котором вы заботитесь:

    myStruct.opcode
    
0 голосов
/ 26 января 2012

он извлечет коды операций в виде перечислений

перечисления нуждаются в разделении запятыми, поэтому он берет OPCODE и ставит после него, что эффективно генерирует

typedef enum simple_op_enum {
NOP_OP, BLAH , WHATEVER , ANOTHER ,
LAST_OP
} simple_op;

Точка перечисленияозначает наличие перечисления всех доступных кодов операций.

LAST_OP полезен для определения таких вещей, как количество используемых вами кодов операций, а также означает, что для последней вещи в списке перечисления нет висящей запятой.

если у вас есть экземпляр структуры, «бла», то вы получите его, набрав blah.opcode = NOP_OP;

...