0

A macro (see below) to return the greater of two numbers is added by 1. But, the effect of the addition is absent.

PS: I have also checked by adding excessive brackets to the macro.

#define max(a,b) (a >= b ? a : b);
void main(){
    int result = max(5,10) + 1; //result = 10
}

Solutions: CASE 1:

By manually replacing the macro in the expression (just as the pre-processor does, I think), the addition is performed correctly.

result = (5 >= 10 ? 5 : 10) + 1;  // Evaluates correctly to 11.

CASE 2: The expression also evaluates correctly when the order of the operands are reversed.

result = 1 + max(5,10); //Evaluates correctly to 11.

Why is the original expression not working as intended while the two solution cases do?

Aadithya V
  • 47
  • 8
  • The signature is `int main()`, `int main(int argc, char* argv[])` or `int main(int argc, char* argv[], char* envp[])`. The signature `void main()` will not be detected as a proper main function – gkhaos Nov 25 '21 at 12:51
  • 1
    See [What should `main()` return in C and C++?](https://stackoverflow.com/q/204476/15168) for a complete and nuanced discussion. – Jonathan Leffler Nov 25 '21 at 14:43
  • @gkhaos in C 'int main()' is not valid, 'int main(void)' is though. – Fredrik Nov 25 '21 at 14:48
  • @Fredrik with most compilers you can omit the explicit non-argument signature – gkhaos Nov 25 '21 at 14:58
  • @gkhaos yes, but according to the standard it should be 'main(void)', so better to suggest the correct one :) In C you should never have an empty argument list, if there is no parameters you should write void. The support for empty list is a very old relic of the C language. – Fredrik Nov 25 '21 at 15:20

2 Answers2

3

You have erroneously added ; to your macro. So the expansion is actually

void main(){
    int result = (5 >= 10 ? 5 : 10); + 1;
}

Here your +1 became a separate statement which does nothing, and result is initialized to 10.

By the way, if you use gcc or Clang, there is an -E flag which will run the actual preprocessor on your source code. The code above was obtained by running gcc -E a.c on your code.

I also recommend compiling with the maximal possible level of warnings. E.g. gcc -Wall -Wextra -Werror a.c hints that there is something wrong:

a.c:2:6: error: return type of 'main' is not 'int' [-Werror=main]
    2 | void main(){
      |      ^~~~
a.c: In function 'main':
a.c:3:28: error: statement with no effect [-Werror=unused-value]
    3 |     int result = max(5,10) + 1; //result = 10
      |                            ^
a.c:3:9: error: unused variable 'result' [-Werror=unused-variable]
    3 |     int result = max(5,10) + 1; //result = 10
      |         ^~~~~~
cc1.exe: all warnings being treated as errors
yeputons
  • 8,478
  • 34
  • 67
3

It is because you placed a semicolon after the macro

#define max(a,b) (a >= b ? a : b);
                               ^^^

Remove it.

The macro should be written like

#define max(a,b) ( ( a ) >= ( b ) ? ( a ) : ( b ) )

So in the first case you in fact has

int result = ( 5 >= 10 ? 5 : 10 );
+ 1;

If you will place the declaration

int result = max(5,10) + 1;

in the file scope before the function main then the compiler will issue an error because there will be statement

+ 1;

and you may not place statements in the file scope.

As for this statement

result = 1 + max(5,10);

then it expands to two statements

result = 1 + ( 5 >= 10 ? 5 : 10 );
;

that is there is also a null statement that does not have an effect.

Pay attention to that according to the C Standard the function main without parameters shall be declared like

int main( void )
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335