8

次のようなものを見たとき、私は組み込みカーネル ソースで作業していました。

#define OMAP_SYS_TIMER_INIT(name, clkev_nr, clkev_src, clksrc_nr, clksrc_src) \
static void __init omap##name##_timer_init(void)                              \
{                                                                             \
    omap2_gp_clockevent_init((clkev_nr), clkev_src);                          \
    omap2_gp_clocksource_init((clksrc_nr), clksrc_src);                       \
}

そして、この ## のもの (名前はわかりません) を使用して実際に何ができるかを確認するプログラムを作成しようとしたとき、動作しませんでした。以下は、その機能をテストするために行ったことです。## 内の引数がリテラルかどうかを確認したいだけですが、コンパイルするコードに何かが明らかに欠けています...

#include <stdio.h>
#include <stdlib.h>

#define DEFINE_1 2
#define DEFINE_2 4
#define DEFINE_3 6

#define DEFINE_i 9

int main(void)
{
  int i;
  for(i=1;i<4;i++) {
    printf("numero %d = %d\n",i,DEFINE_##i##);
  }
  return EXIT_SUCCESS;
}

gcc の出力は次のとおりです。

test.c: In function ‘main’:
test.c:14:5: error: stray ‘##’ in program
test.c:14:33: error: ‘DEFINE_’ undeclared (first use in this function)
test.c:14:33: note: each undeclared identifier is reported only once for each function it appears in
test.c:14:42: error: expected ‘)’ before ‘i’
test.c:14:42: error: stray ‘##’ in program

誰が何が悪いのか知っていますか?ありがとう

4

6 に答える 6

7

これは、C プリプロセッサのトークン連結演算子です。例がコンパイルされない理由は##、マクロ (つまり#defineステートメント) 内で演算子を使用していないためです。

これは、いくつかの詳細情報を含む別の投稿です。

于 2012-12-18T12:57:13.903 に答える
2

##はトークン貼り付け演算子であり、マクロ定義でのみ使用できます。マクロ定義の外では使用できません。

于 2012-12-18T13:01:40.813 に答える
2

##前処理時の連結を意味します。 http://gcc.gnu.org/onlinedocs/cpp/Concatenation.html

于 2012-12-18T12:56:39.443 に答える
2

## は、プリプロセッサ ディレクティブでのみ使用できます。

于 2012-12-18T12:56:48.130 に答える
2

## は、C プリプロセッサ マクロでの連結に使用されます

あなたの例では、アイデアは omap を関数名と連結することです。例えば

OMAP_SYS_TIMER_INIT(foo, ...)

omapfoo という名前の関数を作成します。

于 2012-12-18T12:57:11.020 に答える
1

おそらく、あなたがしようとしているのは、DEFINE_ と (i=1) が ## を使用して連結され、「DEFINE_1」を形成し、それが値 2 のマクロになることです。その場合、問題は、マクロがプリプロセッサであり、値が実行前に取得されることです。したがって、DEFINE_i を探しますが、そのようなマクロはありません。実行時に i=1,2,3.. などになることに注意してください。

于 2012-12-18T12:59:13.593 に答える