6

Why this code gives an error:

#include <stdio.h>
#define Rep (int)6
int main(){
     #if Rep==6
         printf("T");
     #else
         printf("F");

     #endif

return 0;
}
  1. Why does it refuse the casting?
  2. Is it a 'preprocessor error' or a 'compiler error'?
Mina Samir
  • 162
  • 12
  • Can you post the error? – nielsbot Apr 22 '16 at 21:46
  • The error you're probably seeing is because the preprocessor doesn't understand either the type name `int` or the cast operator. The errors or warnings that you're not seeing, or are just ignoring, are because (a) you're missing the required `#include `, (b) `void main()` should be `int main(void)`, and (c) output should be terminated with a newline: `printf("T\n");`. Compilers aren't required to diagnose all of these problems, but you definitely should fix them. – Keith Thompson Apr 22 '16 at 21:52
  • @nielsbot the error from Eclipse IDE :"missing binary operator before token "6" " – Mina Samir Apr 22 '16 at 22:01
  • @MinaSamir, this is actually an excellent hit from Eclipse, please see my answer. – Jens Gustedt Apr 22 '16 at 22:58

2 Answers2

7

This is a preprocessor error. It happens because the preprocessor does not understand how to cast a variable. You cannot use any C code with #if, just simple numbers, or macros which expand to a number.

If you cannot modify Rep, you can work around this with a helper macro, which removes the casting from the beginning:

#include <stdio.h>

#define X(x)
#define Y(x) X x
#define Rep (int)6

int main(void) {
#if Y(Rep) == 6
    printf("%d\n", Y(Rep)); // prints 6
#endif
    return 0;
}
VLL
  • 9,634
  • 1
  • 29
  • 54
  • 7
    That is a devious little macro. – Dietrich Epp Apr 22 '16 at 21:55
  • 1
    Just simply `#define Rep ((int)+6)` would do. But wait, `6` is an `int`, so why the cast all together. – Jens Gustedt Apr 22 '16 at 22:50
  • @JensGustedt I don't agree that's simpler, because it differs from the typical cast syntax. That means you must modify the constant to add the hack. And if you can modify the constant, wouldn't a better idea be to remove the cast that has no effect? – VLL Apr 23 '16 at 07:51
  • Here is a real-world example, in which you cannot modify the constant. http://stackoverflow.com/questions/19406246/remove-cast-from-constant-in-preprocessor – VLL Apr 23 '16 at 07:56
  • @Ville-ValtteriTiittanen sure that there are cases where you don't control the macro. But if you do, you should do it like I describe in my answer. First, avoid the cast completely if literals of the type in question exist, and then use the `+` trick instead of relying on yet another macro. – Jens Gustedt Apr 23 '16 at 09:11
2

Preprossor macros that combine casts and that still should work in #if are easy to write: you just add a little + before the number. In your case

#define Rep ((int)+6)

The preprocessor replaces identifiers that it doesn't know by 0 so the end result is the same value.

But also, the cast in your Rep macro by itself is quite useless. 6 is an int, anyhow. So better avoid a cast for all integer types that have their own literals, combinations of U and L as suffix should do in most cases.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177