简体   繁体   English

如何在 C++ 宏中包含一个换行符或如何使用 C++ 模板来做同样的事情?

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

I saw the following question: How to generate a newline in a cpp macro?我看到以下问题: How to generate a newline in a cpp macro?

Let me give a brief requirement of a need in newline in a C++ preprocessor.让我简要介绍一下 C++ 预处理器中换行的需求。 Am working on ARM Realview compiler 3.1 on a code which uses embedded assembly code with C++ code.我正在研究 ARM Realview 编译器 3.1,该代码使用带有 C++ 代码的嵌入式汇编代码。

#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.上面的宏声明了一个嵌入式程序集 function,它强制要求 function 主体中的每个语句之间换行。

I think this is because the text in the function body is sent blindly to ARM assembler by ARM compiler.我认为这是因为 function 主体中的文本被 ARM 编译器盲目发送给 ARM 汇编器。

Why C++ preprocessor is still now not supporting multi-line replacements?为什么 C++ 预处理器现在仍然不支持多行替换? 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. ARM汇编器/编译器太基础了,GCC中没有像asm volatile这样的API。

DEFINE_FUNCTION macro is used at lots of places, so cannot ignore it also. DEFINE_FUNCTION 宏用在很多地方,所以也不能忽略它。

So, at final resort thinking about the following solutions:因此,最终考虑以下解决方案:

  • Using m4 preprocessor instead of C++ preprocesser使用 m4 预处理器代替 C++ 预处理器
  • Use C++ templates to somehow achieve this and replace DEFINE_FUNCTION using grep/sed使用 C++ 模板以某种方式实现此目的并使用 grep/sed 替换 DEFINE_FUNCTION

Can anyone give me pointers or ways to do the above things?任何人都可以给我指示或方法来做上述事情吗? I cannot use any compiler other than ARM Realview compiler 3.1.除了 ARM Realview 编译器 3.1,我不能使用任何编译器。

I need some expansion like below with new line for, DEFINE_FUNCTION(void*, mov_lt, #0x04) {} ,我需要像下面这样的新行进行一些扩展, 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
  }

I solved the above problem using GNU m4 preprocessor successfully. 我成功地使用GNU m4预处理器解决了上述问题。

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. 使用m4预处理上面的代码解决了代码中的换行符问题。 Ran m4 -P as a prebuild event so that source file is processed even before C preprocessor and compilation stage comes into picture. 将m4 -P作为预建事件,以便在C预处理器和编译阶段进入画面之前处理源文件。

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. 但是在最新的C ++编译器中确实存在良好的宏预处理器的范围。

每个气体版本都有不同的换行替换字符,例如AVR有$寻找ARM气体版本的字符

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. 这正是你所要求的。

I don't know the various C and C++ compilers for ARM, but the following works in 2022 at least with Microsoft compilers for Windows x86 / x64, as well as with Open Watcom compilers (even for DOS):我不知道 ARM 的各种 C 和 C++ 编译器,但以下内容至少在 2022 年适用于 Windows x86 / x64 的 Microsoft 编译器,以及 Open Watcom 编译器(甚至适用于 DOS):

#define MY_MACRO { \
  _asm { \
    _asm MOV AX, 0 \
    _asm MOV BX, 1 \
  } \
}

The preprocessor turns this into one line, removing the continuation characters and the newline characters, but each _asm token separates the instructions as if there was a newline.预处理器将其变成一行,删除连续字符和换行符,但每个_asm标记将指令分隔开,就好像有一个换行符一样。

To stress it again, I have no clue about ARM, and the syntax for GCC x86 / x64 is different anyway, but maybe you can apply this idea to your problem.再次强调一下,我对 ARM 毫无头绪,而且 GCC x86 / x64 的语法无论如何都不一样,但也许你可以将这个想法应用到你的问题中。

PS I am aware that the outmost curly braces are superfluous, but that's the way I prefer when writing macros like that. PS 我知道最外面的花括号是多余的,但这是我在编写这样的宏时更喜欢的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM