C++ マクロに改行を含める方法、または C++ テンプレートを使用して同じことを行う方法は?
-
20-09-2019 - |
質問
次の質問を見ました。cpp マクロで改行を生成するにはどうすればよいですか?
C++ プリプロセッサでの改行の必要性について簡単に説明します。C++ コードで埋め込みアセンブリ コードを使用するコードで ARM Realview コンパイラ 3.1 に取り組んでいます。
#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 マクロは多くの場所で使用されるため、これも無視できません。
そこで、最終手段として次の解決策を考えてみます。
- C++ プリプロセッサの代わりに m4 プリプロセッサを使用する
- 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を使用して上記のコードを前処理コード内の改行の要件の私の問題を解決しました。そのソースファイルをCプリプロセッサとコンパイル段階が絵になっても前に処理されるように事前に作成イベントとしてM4 -Pを走っています。
助けてくれてありがとうと多くの混乱のために申し訳ありません。しかし、実際に最新の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
}
あなたが求めている正確に何である。