-2

I`m struggling with an error in C code.

#define MAX(i, limit) do \
{ \
if (i < limit) \
{ \
i++; \
} \
} while(1)
void main(void)
{ 
MAX(0,3);
}

This leads into the following error.

Error[Pe137]: expression must be a modifiable lvalue

Any ideas? Thank you in advance.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335

2 Answers2

1

For starters according to the C Standard the function main without parameters shall be declared like

int main( void )

You passed to the macro MAX integer constant 0. You may not increase it.

In fact the macro expands to the following code

do
{
   if ( 0 < 3 )
   {
      0++;
   }
} while(1);

Macros are not functions. So in your macro there is performed a direct substitution i and limit for 0 and 3.

You could declare a variable and initialize it with the value 0 and pass it to the macro. In this case you will get an infinite loop.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • `do ... while(1)` isn't a brilliant idea either. There's actually no making sense of a single line in this code. – Lundin Jul 06 '21 at 13:55
  • I think the confusion is that you are calling a macro, not a function. Macros are purely textual substitutions. There is no function named `MAX`, and no variable named `i` being incremented. The macro parameter `0` is inserted wherever `i` appears – Raymond Chen Jul 06 '21 at 14:00
  • @RaymondChen: Re “Macros are purely textual substitutions”: No, they are not. Macro processing substitutes preprocessor tokens, not text, and it processes operators `#` and `##`. The substitutions cannot join or separate tokens, and the `##` cannot create arbitrary text, just valid preprocessor tokens. I understand if you do not want to burden learners with all the details, but neither should they be taught a falsehood which they must unlearn later. They can be taught there is a replacement of source code without being falsely told it is purely textual. – Eric Postpischil Jul 06 '21 at 14:07
  • @EricPostpischil I should not have used the word "purely", but I think the overly-pedantic clarification obscures the issue. (After all, it doesn't change "while" to "wh0le" either.) – Raymond Chen Jul 06 '21 at 14:43
0

In this use case you try to increment 0 which is not possible.

do {} while in this case makes no sense at all.

I would write it this way :

#define MAX(i, limit)  (((i) < (limit)) ? (i) + 1 : (i))  

void main(void)
{ 
    int i = 5;
    i = MAX(i, 7);
    printf("%d\n", MAX(0,3));
    printf("%d\n", i);
    MAX(0,3);  // this statement has no effect
}

And (probably) you would not try to:

0 = MAX(0,3);

You need to remember that is the macro and i and limit will be evaluated as many times as they are in the macro. Example:

#define MAX(i, limit)  (((i) < (limit)) ? i + 1 : i)

int y = 1;
int increase(void)
{
    y++;
}

void main(void)
{ 
    printf("%d\n", MAX(increase(),3));
}

Some expressions may lead to the undefined behaviour:

#include <stdio.h>
#define MAX(i, limit)  (((i) < (limit)) ? i + 1 : i)

int y = 1;

void main(void)
{ 
    printf("%d\n", MAX(y++,3));
}
0___________
  • 60,014
  • 4
  • 34
  • 74