enum --enumeration

The enum enum makes it easy to write consecutive integer constants. Constant name 1 is 0, constant name 2 is 1, and constant name 3 is 2.

enum {
  Constant name 1,
  Constant name 2,
  Constant name 3,
  ...
};;

This is a sample using enum type enum. Since enum is often used in combination with switch statement, I used it as a sample of switch statement.

#include <stdint.h>
#include <stdio.h>

enum {
  SPVM_OP_C_ID_IF,
  SPVM_OP_C_ID_UNLESS,
  SPVM_OP_C_ID_ELSIF,
  SPVM_OP_C_ID_ELSE,
  SPVM_OP_C_ID_FOR,
};;

int main (void) {
  
  int32_t id = SPVM_OP_C_ID_UNLESS;
  
  switch (id) {
    case SPVM_OP_C_ID_IF: {
      printf("IF\n");
      break;
    }
    case SPVM_OP_C_ID_UNLESS: {
      printf("UNLESS\n");
      break;
    }
    case SPVM_OP_C_ID_ELSIF: {
      printf("ELSIF\n");
      break;
    }
    case SPVM_OP_C_ID_ELSE: {
      printf("ELSE\n");
      break;
    }
    case SPVM_OP_C_ID_FOR: {
      printf("FOR\n");
      break;
    }
    default: {
      printf("No Match\n");
    }
  }
}

The enumerated identifier can be any identifier name, but since there is no namespace in C language, in the sample, the name "SPVM_OP_C_XXX" (spvm_op.c source code) as if it had a namespace. It uses the constant "constant" definition in).

Enums are semantically the same as macro constant definitions

Enums are semantically the same as macro constant definitions.

// Integer definition using enumeration
enum {
  SPVM_OP_C_ID_IF,
  SPVM_OP_C_ID_UNLESS,
  SPVM_OP_C_ID_ELSIF,
}

// Integer definition using macro
#define SPVM_OP_C_ID_IF 0
#define SPVM_OP_C_ID_UNLESS 1
#define SPVM_OP_C_ID_ELSIF 2

Although semantically the same, enums are characterized by being processed by the compiler rather than the preprocessor, unlike macros. Expanded to a constant by the compiler.

The best practice in C is to use macros only where they are needed, so if you want contiguous integer constants, it's best to use enums.

Enumeration questions

Enumerates enumerated questions.

Is it possible to change the starting value of an integer in an enum?

Yes, I can. To change the starting value of an integer, write "constant name = number". The next low number will be the incremented value.

enum {
  SPVM_OP_C_ID_IF = 3, # 3
  SPVM_OP_C_ID_UNLESS, # 4
  SPVM_OP_C_ID_ELSIF, # 5
  SPVM_OP_C_ID_ELSE = 10, # 10
  SPVM_OP_C_ID_FOR, # 11
};;

Is it possible to use floating point in enums?

can not. If you want to define a floating point constant, use a macro.

#define SPVM_OP_C_ID_IF 5.23

Are enum identifiers uppercase?

As a general practice in C, it's best to write constants in uppercase.

Which side of the enum is the type?

Enums can be named like types and treated like types.

enum SPVM_OP_C_ID_TYPE {
  SPVM_OP_C_ID_IF,
  SPVM_OP_C_ID_UNLESS,
  SPVM_OP_C_ID_ELSIF,
  SPVM_OP_C_ID_ELSE,
  SPVM_OP_C_ID_FOR,
};;

However, the behavior when assigning to an enumeration type is not defined in the C language specification and depends on the processing system, so I think that it is better not to use the enumeration type as a type too much.

Shouldn't I use strings instead of enums?

Enumerations are the ability to give an identifier, or name, to an integer. If so, shouldn't I use strings from the beginning?

I think this is the best option for programming languages ​​like Perl that have dynamic types.

if ($id eq'if') {
  
}
elsif ($id eq'unless') {
  
}

However, if you use C language, you probably use it with the motive of wanting to speed up performance. If the number of identifiers exceeds a certain number (about 10?), It is the fastest to make an integer judgment with a switch statement and jump.

Also, for C language string comparison, you need to use the strcmp function, and the string does not end with "\ 0", and there is a possibility that it will be read to an unintended area.

As you can see, there are many things to think about in C strings, so it is easier to define integers in enumerations.

Where do you define enums when compiling separately?

The enumeration type is described in the header file as the configuration when compiling the header using split compilation and the source code separately.

Constant definitions such as macro constants and enumerated types are described in the header.

spvm_op.h

enum {
  SPVM_OP_C_ID_IF,
  SPVM_OP_C_ID_UNLESS,
  SPVM_OP_C_ID_ELSIF,
  SPVM_OP_C_ID_ELSE,
  SPVM_OP_C_ID_FOR,
};;

spvm_op.c

#include <stdint.h>
#include <stdio.h>

#include "spvm_op.h"

int main (void) {
  
  int32_t id = SPVM_OP_C_ID_UNLESS;
  
  switch (id) {
    case SPVM_OP_C_ID_IF: {
      printf("IF\n");
      break;
    }
    case SPVM_OP_C_ID_UNLESS: {
      printf("UNLESS\n");
      break;
    }
    case SPVM_OP_C_ID_ELSIF: {
      printf("ELSIF\n");
      break;
    }
    case SPVM_OP_C_ID_ELSE: {
      printf("ELSE\n");
      break;
    }
    case SPVM_OP_C_ID_FOR: {
      printf("FOR\n");
      break;
    }
    default: {
      printf("No Match\n");
    }
  }
}

Associated Information