Frage

Zum Beispiel, wie der 'func_name' zu vermeiden Schreiben zweimal?

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

Ich möchte die Single Point of Truth Regel folgen.

Version von C-Präprozessor:

$ cpp --version
cpp (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)
War es hilfreich?

Lösung

Wer Shy ist * gab man den Keim ein answer , sondern nur der Keim. Die grundlegende Technik einen Wert in eine Zeichenfolge in der C Pre-Prozessor für die Umwandlung ist in der Tat über die ‚#‘ Operator, sondern ein einfaches Umschrift der vorgeschlagenen Lösung wird ein Übersetzungsfehler:

#define TEST_FUNC test_func
#define TEST_FUNC_NAME #TEST_FUNC

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

Die Syntaxfehler sind auf dem 'puts ()' line - das Problem eine 'Streu #' ist in der Quelle

.

In Abschnitt 6.10.3.2 des C-Standard, 'Der # Operator', heißt es:

  

Jede # Vorverarbeitung Token in der   Ersatzliste für eine funktionsähnliche   Makro wird von einem Parameter folgen   als die nächste Vorverarbeitung Token in der   Ersatz-Liste.

Das Problem ist, dass Sie Makro Argumente in Strings umwandeln kann -. Sie können jedoch keine zufällige Elemente umwandeln, die nicht Makro Argumente

Also, um zu erreichen, um die Wirkung Sie nach, Sie ganz sicher einige zusätzliche Arbeit zu tun haben.

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

Ich bin mir nicht ganz klar, wie Sie planen, die Makros zu verwenden, und wie planen Sie Wiederholung ganz zu vermeiden. Diese etwas aufwendigere Beispiel könnte informativer sein. Die Verwendung eines Makro entspricht STR_VALUE ist ein Idiom, das notwendig ist, um das gewünschte Ergebnis zu erhalten.

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

* Zu der Zeit, wenn diese Antwort zuerst geschrieben wurde, shoosh den Namen verwendet ‚Shy‘ als Teil des Namens.

Andere Tipps

@ Jonathan Leffler: Danke. Ihre Lösung funktioniert.

Ein komplettes Arbeitsbeispiel:

/** 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;
}

Beispiel:

$ gcc -Wall -DTEST_FUN=another_func macro_sub.c -o macro_sub && ./macro_sub
do something else
TEST_FUN_NAME=another_func
#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;
}

Referenz: Wikipedia C Präprozessor Seite

#define TEST_FUN_NAME #FUNC_NAME

siehe

hier

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top