How to include a newline in a C++ macro or how to use C++ templates to do the same?

By : vprajan
Source: Stackoverflow.com
Question!

I saw the following question: http://stackoverflow.com/questions/98944/how-to-generate-a-newline-in-a-cpp-macro

Let me give a brief requirement of a need in newline in a C++ preprocessor. Am working on ARM Realview compiler 3.1 on a code which uses embedded assembly code with C++ code.

#define DEFINE_FUNCTION(rtype, op, val) \
    __asm rtype nt_##op(void*) { \   
      str lr, [sp, ##val];bl vThunk_##op;ldr lr, [sp,##val];bx lr; \
    } \
   void vThunk_##op(void*)

DEFINE_FUNCTION(void*, mov_lt, #0x04)
{
     // do some operation
}

The above macro declares a embedded assembly function which forcefully requires newline between each statements in the function body.

I think this is because the text in the function body is sent blindly to ARM assembler by ARM compiler.

Why C++ preprocessor is still now not supporting multi-line replacements ? and also i cannot use # in the replacement string. for example, for this kind of assembly,

str lr, [sp, #0x04]

I tried lots of methods and ways, but nothing really worked out. ARM assembler/compiler is so basic that there is no API like asm volatile in GCC.

DEFINE_FUNCTION macro is used at lots of places, so cannot ignore it also.

So, at final resort thinking about the following solutions:

  • Using m4 preprocessor instead of C++ preprocesser
  • Use C++ templates to somehow achieve this and replace DEFINE_FUNCTION using grep/sed

Can anyone give me pointers or ways to do the above things ? I cannot use any compiler other than ARM Realview compiler 3.1.

I need some expansion like below with new line for, DEFINE_FUNCTION(void*, mov_lt, #0x04) {},

__asm void* nt_mov_lt(void*) {   
      str lr, [sp, 0x04];
      bl vThunk_mov_lt;
      ldr lr, [sp,0x04];
      bx lr;
    }
 void vThunk_mov_lt(void*)
 {
     // do something
  }
By : vprajan


Answers

Your example is extremely confusing, but wouldn't this work?

#define DEFINE_FUNCTION(rtype, op, val) \
    __asm rtype nt_##op(void*) { \   
      str lr, [sp, val];\
      bl vThunk_##op;\
      ldr lr, [sp,val];\
      bx lr;\
    }\
   void vThunk_##op(void*)

and when called like

DEFINE_FUNCTION(void*, mov_lt, 0x04)  // notice no # here
{
     // do some operation
}

you'd get

__asm void* nt_mov_lt(void*) {   
      str lr, [sp, 0x04];
      bl vThunk_mov_lt;
      ldr lr, [sp,0x04];
      bx lr;
    }
 void vThunk_mov_lt(void*)
 {
     // do something
 }

which is exactly what you're asking for.

By : Blindy


every gas version has different newline substitution character e.g. AVR has $ look for the character for ARM gas version

By : trzeci


I solved the above problem using GNU m4 preprocessor successfully.

m4_define('DEFINE_FUNCTION','
     __asm rtype nt_$2(void*) {  
      str lr, [sp, $3];
      bl vThunk_$1;
      ldr lr, [sp,$3];
      bx lr;
    } 
   void vThunk_$2(void*)')

DEFINE_FUNCTION(void*, mov_lt, 0x04)
{
}

Preprocessing the above code using m4 solved my problem of newline requirement in code. Ran m4 -P as a prebuild event so that source file is processed even before C preprocessor and compilation stage comes into picture.

Thanks for the help and sorry for confusing a lot. But there is really a scope for good macro pre-processor in latest C++ compilers.

By : vprajan


This video can help you solving your question :)
By: admin