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?

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
  • 91,854
  • 11
  • 113
  • 173
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
  • 375,615
  • 96
  • 501
  • 581
  • 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,612
  • 25
  • 32