55

For example, how to avoid writing the 'func_name' twice?

#ifndef TEST_FUN
#  define TEST_FUN func_name
#  define TEST_FUN_NAME "func_name"
#endif

I'd like to follow the Single Point of Truth rule.

Version of C preprocessor:

$ cpp --version
cpp (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)
4

4 に答える 4

83

恥ずかしがり屋*である彼はあなたに答えの胚芽を与えましたが、胚芽だけです。Cプリプロセッサで値を文字列に変換するための基本的な手法は、実際には「#」演算子を使用することですが、提案されたソリューションの単純な音訳では、コンパイルエラーが発生します。

#define TEST_FUNC test_func
#define TEST_FUNC_NAME #TEST_FUNC

#include <stdio.h>
int main(void)
{
    puts(TEST_FUNC_NAME);
    return(0);
}

構文エラーは「puts()」行にあります-問題はソースの「漂遊#」です。

C標準のセクション6.10.3.2、「#演算子」では、次のように述べています。

関数のようなマクロの置換リスト内の各#前処理トークンの後に、置換リスト内の次の前処理トークンとしてのパラメーターが続くものとします。

問題は、マクロ引数を文字列に変換できることですが、マクロ引数ではないランダムなアイテムを変換することはできません。

ですから、あなたが求めている効果を達成するために、あなたは確かにいくつかの追加の仕事をしなければなりません。

#define FUNCTION_NAME(name) #name
#define TEST_FUNC_NAME  FUNCTION_NAME(test_func)

#include <stdio.h>

int main(void)
{
    puts(TEST_FUNC_NAME);
    return(0);
}

マクロをどのように使用する予定であるか、および繰り返しを完全に回避する方法については、完全には明確ではありません。この少し手の込んだ例は、より有益かもしれません。STR_VALUEと同等のマクロの使用は、目的の結果を得るために必要なイディオムです。

#define STR_VALUE(arg)      #arg
#define FUNCTION_NAME(name) STR_VALUE(name)

#define TEST_FUNC      test_func
#define TEST_FUNC_NAME FUNCTION_NAME(TEST_FUNC)

#include <stdio.h>

static void TEST_FUNC(void)
{
    printf("In function %s\n", TEST_FUNC_NAME);
}

int main(void)
{
    puts(TEST_FUNC_NAME);
    TEST_FUNC();
    return(0);
}

*この回答が最初に書かれたとき、shooshの名前は名前の一部として「Shy」を使用していました。

于 2008-10-12T20:35:11.890 に答える
20

@ジョナサン・レフラー: ありがとう。あなたのソリューションは機能します。

完全な作業例:

/** compile-time dispatch 

   $ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub
*/
#include <stdio.h>

#define QUOTE(name) #name
#define STR(macro) QUOTE(macro)

#ifndef TEST_FUN
#  define TEST_FUN some_func
#endif

#define TEST_FUN_NAME STR(TEST_FUN)

void some_func(void)
{
  printf("some_func() called\n");
}

void another_func(void)
{
  printf("do something else\n");
}

int main(void)
{
  TEST_FUN();
  printf("TEST_FUN_NAME=%s\n", TEST_FUN_NAME);
  return 0;
}

例:

$ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub
do something else
TEST_FUN_NAME=another_func
于 2008-10-12T21:10:34.830 に答える
0
#include <stdio.h>

#define QUOTEME(x) #x

#ifndef TEST_FUN
#  define TEST_FUN func_name
#  define TEST_FUN_NAME QUOTEME(TEST_FUN)
#endif

int main(void)
{
    puts(TEST_FUN_NAME);
    return 0;
}

参考:ウィキペディアのC プリプロセッサのページ

于 2008-10-12T20:27:18.163 に答える
-1

#define TEST_FUN_NAME #FUNC_NAME

see here

于 2008-10-12T20:19:07.820 に答える