簡體   English   中英

如何在 C++ 宏中包含一個換行符或如何使用 C++ 模板來做同樣的事情?

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

我看到以下問題: How to generate a newline in a cpp macro?

讓我簡要介紹一下 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
}

上面的宏聲明了一個嵌入式程序集 function,它強制要求 function 主體中的每個語句之間換行。

我認為這是因為 function 主體中的文本被 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
  }

我成功地使用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 ++編譯器中確實存在良好的宏預處理器的范圍。

每個氣體版本都有不同的換行替換字符,例如AVR有$尋找ARM氣體版本的字符

你的例子非常令人困惑,但這不會起作用嗎?

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

這正是你所要求的。

我不知道 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 我知道最外面的花括號是多余的,但這是我在編寫這樣的宏時更喜歡的方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM