1

I am trying to optimize a life game. I need to change this code from the header file:

  #define MASK(col) (0x80 >> ((col) & 7))

(The variable "col" is a variable that will save the column, it goes from 0 to 8)

To something like this:

int array[9] = { 0, 64, 32, 16, 8, 4, 2, 1};
  #define MASK(col) (array[col])

(((0) & 7) = 0, ((1) & 7) = 64, ((2) & 7) = 32, ((3) & 16)...)

The error I am getting with this code is the following:

"#10010 errors encountered during linking "life.out" not built"
"#10056 "array" redefined: first defined in './lifelib.obj', redefined in 
'./life.obj'"

(Ps.: I've changed the name of the array to something like: "OKDPSAdiahodakDSA" and I still got the same error)

PS: This error only happens when I make this change. The entire code is working fine.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278

3 Answers3

2

I think you have defined the array in the header file and you have included it (directly or indirectly) in two C files:

  • life.c
  • lifelib.c

When the compiler generate the obj files, it sees a definition of array in each file, so it includes it in both obj files. Then, when the linker tries to generate the file it finds two duplicated arrays, one for each obj.

You should declare the variable extern in the header and define it only in one c file. You can find more information here.

Community
  • 1
  • 1
J. Calleja
  • 4,855
  • 2
  • 33
  • 54
0

The problem is that you're using a macro.

C macros are processed by the C preprocessor, which runs before your code compiles. So macros don't know anything about variables, which only exist as named entities during compilation. You are trying to use your MASK macro as if it knew the variables array and col exist, but macros don't know anything about arrays - they just do literal text substitution.

So if you do something like

int x = MASK(9);

the text

int x = array[9];

gets injected into your code. This is why you're seeing errors related to array even if you change the name of your array.

The easiest way to solve this would be to change the name of your array into something that you know will never be used, like __life_mask_array.

So you could change your code to something like:

int __life_mask_array[9] = { 0, 64, 32, 16, 8, 4, 2, 1};
#define MASK(col) (__life_mask_array[col])

Which would make a name collision less likely.

Of course, unless using a macro for this is sorely needed, you could do away with the macro altogether and just access your array. C macros tend to be more trouble than they are worth, because they do text substitution, which may cause stuff to behave unexpectedly if a macro uses a name that exists in its enclosing scope. It is a usual practice to prefix variable names used in macros with underscores in order to avoid name collisions, but there is no surefire way to guarantee you won't run into trouble.

Pedro Castilho
  • 10,174
  • 2
  • 28
  • 39
  • Hm, what is calling MASK is another macro: – Marcelo Almeida Mar 30 '17 at 21:27
  • #define CELL_VALUE(row, col) (window[(row)][(col) >> 3] & MASK(col) ? 1 : 0) – Marcelo Almeida Mar 30 '17 at 21:29
  • What do you suggest me to do so I can resolve my problem? – Marcelo Almeida Mar 30 '17 at 21:29
  • C macros tend to be more trouble than they are worth, because they do text substitution, which may cause stuff to behave unexpectedly if a macro uses a name that exists in its enclosing scope. It is a usual practice to prefix variable names used in macros with underscores in order to avoid name collisions, but there is no surefire way to guarantee you won't run into trouble. (I added this and a suggested solution to my answer) In the CELL_VALUE macro you could change `row` to `_row` and `col` to `_col`. – Pedro Castilho Mar 30 '17 at 21:31
  • Didn't work =( But thank you very much for your help! – Marcelo Almeida Mar 30 '17 at 21:38
  • "I am trying to optimize a life game." Is access to your mask array without macros really one of the major bottlenecks in your program? I'm just curious. – synchronizer Mar 30 '17 at 21:45
  • It is the same. I did what J. Calleja told me to do, and it compiled, but it messed up some stuff. – Marcelo Almeida Mar 30 '17 at 21:54
  • @synchronizer It is called hundred times per main loop. It is called quite a few times – Marcelo Almeida Mar 30 '17 at 21:55
0

Thank you so much. My code basically doubled the speed. Everyone here helped A TON. I wish I could give the "best answer" check mark to everyone.

I did was the following: I changed this part of my 'life.h' file:

#define MASK(col) (0x80 >> ((col) % 8))

To this one:

  #define MASK(col) (0x80 >> ((col) & 7))

So I deleted/erase/commented it out the '#define MASK' and did the following:

On my 'life.c' file I created the following array:

int __life_mask_array[] = { 128, 64, 32, 16, 8, 4, 2, 1 };

And on my 'life.h' file had the following:

extern int __life_mask_array[]
#define MASK(col) (array[(col)&7])