Home > Software engineering >  How to loop over variable names?
How to loop over variable names?

Time:01-12

I need to do some assigns as follows.

In struct REGS, tiles are arranged by names;

while on outside, tiles are arranged by indices.

#include <stdio.h>

typedef struct TILE {} TILE;

typedef struct REGS {
    TILE tile00, tile01, tile02,
         tile10, tile11, tile12,
         tile20, tile21, tile22;
} REGS;

int main() {
    TILE tiles[3][3];
    REGS regs;

    regs.tile00 = tiles[0][0];
    regs.tile01 = tiles[0][1];
    regs.tile02 = tiles[0][2];
    regs.tile10 = tiles[1][0];
    regs.tile11 = tiles[1][1];
    regs.tile12 = tiles[1][2];
    regs.tile20 = tiles[2][0];
    regs.tile21 = tiles[2][1];
    regs.tile22 = tiles[2][2];

    return 0;
}

so I suppose I need a loop like:

for (int i = 0; i < 3;   i) {
    for (int j = 0; j < 3;   j) {
        // not real code
        regs.tile##i##j = tiles[i][j];
    }
}

for doing that, I defined some macros:

#define TILE_MEM(prefix, i, j) prefix##i##j

#define WRITE_TILE(base, mem, value) (base.mem = value;)

#define MACRO_LOOP(i,j) (WRITE_TILE(regs, TILE_MEM(tile, i, j), tiles[i][j]))

then I did this:

for (int i = 0; i < 3;   i) {
    for (int j = 0; j < 3;   j) {
        MACRO_LOOP(i, j);
    }
}

but it doesn't compile.

PLEASE HELP!

CodePudding user response:

Macros are the wrong solution and they only exist at compile-time, so you can't use them together with run-time values.

The standard way of creating a type where you can either access items by individual names or as an array, is to use a union:

typedef union {
  struct  // anonymous struct, must be compiled with a standard C compiler
  {
    TILE tile00, tile01, tile02,
         tile10, tile11, tile12,
         tile20, tile21, tile22;
  };
  TILE tile [3][3];
} REGS;

Now you can either use individual names:

regs.tile00 = tiles[0][0];
regs.tile01 = tiles[0][1];

Or the array type:

for(size_t i=0; i<3; i  )
{
  for(size_t j=0; j<3; j  )
  {
    regs.tile[i][j] = tiles[i][j];
  }
}

(Do keep struct alignment/padding in mind however, since there's some special cases where that might trip union type punning over.)

  • Related