0

I have a macro that displays the month from __DATE__ as a numeric value string literal:

#define MONTH (\
  __DATE__[2] == 'n' ? (__DATE__[1] == 'a' ? "01" : "06") \
: __DATE__[2] == 'b' ? "02" \
: __DATE__[2] == 'r' ? (__DATE__[0] == 'M' ? "03" : "04") \
: __DATE__[2] == 'y' ? "05" \
: __DATE__[2] == 'l' ? "07" \
: __DATE__[2] == 'g' ? "08" \
: __DATE__[2] == 'p' ? "09" \
: __DATE__[2] == 't' ? "10" \
: __DATE__[2] == 'v' ? "11" \
: "12")

This works fine and produces the month I'm looking for. printf("%s", MONTH);. However, I'm trying to add this to a larger group of macros and am having trouble:

#define MYMONTH "M" MONTH

should produce the string: M11 right now. But instead, it produces the following compiler error:

error: called object is not a function or function pointer
#define MYMONTH   "M" MONTH

I know you can combine string literals with a macro by appending them:

#define COMMA ","
#define EXCLA "!"
#define MYSTR "Hello" COMMA " world" EXCLA

But why won't it work when there is logic involved?

linsek
  • 3,334
  • 9
  • 42
  • 55
  • 3
    The preprocessor can concatenate string *literals* only. The evaluation of that logic is not done at preprocessing time, but later on—probably at compile time, because it’s a constant expression. E.g., if `__DATE__` expands to `"Oct 31 2016"` then `MONTH` expands to the expression `("Oct 31 2016"[2] == 'n' ? …)`, not a literal. – Jon Purdy Nov 01 '16 at 22:26

1 Answers1

1

Macros are just a string copy done in preprocessing.

If we copy your MONTH macro into MYMONTH we get:

#define MYMONTH "M" (\
  __DATE__[2] == 'n' ? (__DATE__[1] == 'a' ? "01" : "06") \
: __DATE__[2] == 'b' ? "02" \
: __DATE__[2] == 'r' ? (__DATE__[0] == 'M' ? "03" : "04") \
: __DATE__[2] == 'y' ? "05" \
: __DATE__[2] == 'l' ? "07" \
: __DATE__[2] == 'g' ? "08" \
: __DATE__[2] == 'p' ? "09" \
: __DATE__[2] == 't' ? "10" \
: __DATE__[2] == 'v' ? "11" \
: "12")

Which to the compiler looks like you are trying "M"(<some string here>)

mascoj
  • 1,313
  • 14
  • 27
  • I'm not sure I follow. What is the problem with that? You can concat string literals together with macros as I illustrated in the question. `MONTH` will evaluate to be a string literal ("11" right now). So what is wrong with `#define MYMONTH "M" MONTH`? – linsek Nov 01 '16 at 22:15
  • 2
    ```MONTH``` is evaluated to ```("11")``` so your ```MYMONTH``` evaluates to ```"M"("11")``` – mascoj Nov 01 '16 at 22:20
  • 2
    @linsek: you can concatenate string *literals*. You cannot concatenate *expressions*. – rici Nov 01 '16 at 23:00