如何在 C++ 中包含换行符宏或如何使用 C++模板也可以做同样的事情吗?

发布于 2024-08-06 20:18:05 字数 1297 浏览 5 评论 0原文

我看到了以下问题: 如何在 cpp 宏中生成换行符?

让我简要介绍一下 C++ 预处理器中换行符的需求。我正在开发 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
}

上面的宏声明了一个嵌入式汇编函数,该函数在函数体中的每个语句之间强制要求换行符。

我认为这是因为ARM编译器盲目地将函数体中的文本发送给ARM汇编器。

为什么 C++ 预处理器现在仍然不支持多行替换?而且我也不能在替换字符串中使用#。比如这种组装,

str lr, [sp, #0x04]

我尝试了很多方法和途径,但都没有什么效果。 ARM 汇编器/编译器非常基础,以至于 GCC 中没有像 asm volatile 这样的 API。

DEFINE_FUNCTION 宏在很多地方都使用,所以也不能忽略它。

因此,最后考虑以下解决方案:

  • 使用 m4 预处理器而不是 C++ 预处理器
  • 使用 C++ 模板以某种方式实现此目的并使用 grep/sed 替换 DEFINE_FUNCTION

任何人都可以给我指示或方法来执行上述操作吗?我无法使用除 ARM Realview 编译器 3.1 之外的任何编译器。

我需要一些扩展,如下所示,使用新行 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 saw the following question:
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
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

乱世争霸 2024-08-13 20:18:05

我使用 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)
{
}

使用 m4 预处理上述代码解决了代码中换行符要求的问题。将 m4 -P 作为预构建事件运行,以便在 C 预处理器和编译阶段出现之前就处理源文件。

感谢您的帮助,很抱歉让您感到困惑。但在最新的 C++ 编译器中确实存在良好的宏预处理器的空间。

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.

清风疏影 2024-08-13 20:18:05

每个gas版本都有不同的换行替换字符
例如AVR有$
寻找ARM Gas版本的角色

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

网名女生简单气质 2024-08-13 20:18:05

我不知道 ARM 的各种 C 和 C++ 编译器,但以下内容至少在 2022 年适用于 Windows x86 / x64 的 Microsoft 编译器,以及 Open Watcom 编译器(甚至适用于 DOS):

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

预处理器将其转换为一个行,删除连续字符和换行符,但每个 _asm 标记将指令分隔开,就像有换行符一样。

再次强调一下,我对 ARM 一无所知,而且 GCC x86 / x64 的语法无论如何都是不同的,但也许你可以将这个想法应用到你的问题上。

PS 我知道最外面的花括号是多余的,但这是我在编写这样的宏时更喜欢的方式。

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):

#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.

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.

P.S. I am aware that the outmost curly braces are superfluous, but that's the way I prefer when writing macros like that.

眼藏柔 2024-08-13 20:18:05

你的例子非常令人困惑,但这行不通?

#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)  // notice no # here
{
     // do some operation
}

你会得到

__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
 }

这正是你所要求的。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文