6

I have a situation like this

#define PRE 0xF1

#define SR0 0B0000
#define SR1 0B0001
#define SR2 0B0010
#define SR3 0B0011

#define VIOTA(A0)  asm(".byte PRE, A0")

int main()
{
  VIOTA(SR1);
  return 0;
}

I have a top-level macro that expands out however the expansion contains more macros. These aren't being expanded and causing some problems.

The behaviour that I desire is that the end expansion is

asm(".byte 0xF1, 0B0000")

Here the inner macros have been expanded. I'm really not sure what I'm doing wrong at all. Any advice?

  • An additional bit of information. Yes, the quotations are the problem here but it's important that the two existing double quotes end up in the final expanded line. Perhaps there's some way to escape the quotes? – Jimmy Cracked Corn Jul 13 '11 at 23:09
  • possible duplicate of [C Preprocessor, Stringify the result of a macro](http://stackoverflow.com/questions/3419332/c-preprocessor-stringify-the-result-of-a-macro) – Ciro Santilli OurBigBook.com May 31 '15 at 23:38

3 Answers3

9
#define S(x) #x
#define SX(x) S(x)

#define VIOTA(A0) asm(".byte " SX(PRE) ", " SX(A0))

See details here: C Preprocessor, Stringify the result of a macro

Community
  • 1
  • 1
Karoly Horvath
  • 94,607
  • 11
  • 117
  • 176
1

Use the stringizing operator # to convert tokens into strings. However, since the stringizing operator can only be applied to macro parameters, you need to add some extra layers of macros:

#define PRE 0xF1

#define SR0 0B0000
#define SR1 0B0001
#define SR2 0B0010
#define SR3 0B0011

#define VIOTA(A0) VIOTA_HELPER1(PRE, A0)
#define VIOTA_HELPER1(PRE, A0) VIOTA_HELPER2(PRE, A0)
#define VIOTA_HELPER2(PRE, A0) asm(".byte" #PRE ", " #A0)

int main(void)
{
  VIOTA(SR1);
  return 0;
}

After preprocessing, this expands to this:

int main(void)
{
  asm(".byte " "0xF1" ", " "0B0001");
  return 0;
}

String constants get concatenated at compile time, so this is equivalent to asm(".byte 0xF1, 0B0001");.

Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • String constants are concatenated by the preprocessor, I'd have thought? – Lightness Races in Orbit Dec 23 '12 at 14:00
  • C++11 2.14.5/13 says it's done in translation phase 6. That's me told. – Lightness Races in Orbit Dec 23 '12 at 14:02
  • @Lightness: If you want to be pedantic, then there's not really a separate "preprocessor" and "compiler" but rather a single "translator" with a number of phases of translation. C99 §5.1.1.2 puts string literal concatenation in phase 6 of 8 for C code, while C++03 §2.1 puts it in phase 6 of 9 for C++ code (I don't have a copy of C++11 handy). Both GCC and Clang do not concatenate string literals if you just run the preprocessor (the `-E` argument) without compiling. – Adam Rosenfield Dec 30 '12 at 02:55
  • @AdamRosenfield: C++11 2.2/4 is specifically explicit, in my view (it begins `Preprocessing directives are executed` and goes on to list the things that the preprocessor does, no more no less), to call phase 4 the "preprocessing phase". – Lightness Races in Orbit Dec 30 '12 at 11:23
0

You are making PRE part of the string that is passed to asm(). Macros in strings are not expanded.

This seems to work for me:

  #define PRE 0xF1

  #define SR0 0B0000
  #define SR1 0B0001
  #define SR2 0B0010
  #define SR3 0B0011

  #define str(s) #s
  #define VIOTA(PRE, A0)  asm( ".byte " str(PRE) ", " str(A0) )

  int main()
  {    
       VIOTA(PRE, SR1);
         return 0;
  }
BjoernD
  • 4,720
  • 27
  • 32