Tree
Tree

Reputation: 145

Why is using a macro in my code produces errors?

I wrote a macro that sums the number of odd indexed bits which are turned on.

A few examples:

In the variable that contains the following bits:

10010101 

Only the bit at index 7 is turned on, there is only 1 odd indexed bit that is turned on,so the answer is 1.

In the variable that contains the following bits:

00101011 

Bit at index 1 is turned on, bit at index 3 is turned on and bit at index 5 is turned on, and therefore there is a total of 3 odd indexed bits that are turned on, so the answer is 3.

I wrote a main function to test this macro.

Here's the entire program:

#include <stdio.h>

#define ODD(n)\
 int count = 0;\
 int i = 1; \
while(n>>i)\
{\
    if( ((n>>i)%2) == 1)\
        count++;\
        i = i+2;\
}\




int main()
{
  int i;
  int j;
  int array1[] = {1,2,3,4};
 /*array1 contains (binary representation):
  00000001
  00000010
  00000011
  00000100
  After passing these into the macro:
  00000001 ----> 0 odd indexed bits are turned on
  00000010 ---->1 odd indexed bit is turned on
  00000011 ---->1 odd indexed bit is turned on
  00000100 ----> 0 odd indexed bits is turned on

 */
int array2[4];
for(i=0; i<4; i++)
{
    array2[i] = ODD(array1[i]);
}

for(j=0; j<4; j++)
{
    printf("Array2: %d\n",array2[j]);
}




  return 0;
}

I have no idea why I got the following errors:

odd.c: In function ���main���:
odd.c:4:5: error: expected expression before ���int���
 int count = 0;\

odd.c:34:19: note: in expansion of macro ���ODD���
   array2[i] = ODD(array1[i]);
               ^

odd.c:8:13: error: ���count��� undeclared (first use in this function)
         count++;\
         ^

count is declared so I don't know what is the problem with it.

Why did I get these errors and how can I fix them?

Upvotes: 0

Views: 40

Answers (1)

You got an error because a macro is not a function. It's a token expansion mechanism, and it expands to the following nonsense:

array2[i] = int count = 0;
while(array1[i]>>1)\
{\
    if( ((array1[i]>>1)%2) == 1)\
        count++;\
}\

Write it as function, and then you can treat it as though it's returning an actual result:

int odd(int n) {
  int count = 0;
  while(n>>1)
  {
    if( ((n>>1)%2) == 1)
        count++;
  }
  return count;
}

If you insist on writing this with a macro, then you'll need to restructure it:

#define ODD(n, res) do { \
  int count = 0; \
  while(n>>1)\
  {\
    if( ((n>>1)%2) == 1)\
      count++;\
  }\
  (res) = count;\
} while(0)

To define a variable, you must introduce a scope, so a do while loop is added for that effect. This particular loop construct has the nice feature of not producing a warning about empty statements when you write a statement terminator after the macro invocation (ODD(...);).

The location target for the result should be passed as another argument to the macro, like so:

ODD(array1[i], array2[i]);

Upvotes: 3

Related Questions