Domanda

Ad esempio, come evitare di scrivere due volte il nome_funzione?

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

Mi piacerebbe seguire la Single Point of Truth .

Versione del preprocessore C:

$ cpp --version
cpp (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)
È stato utile?

Soluzione

Chi è timido * ti ha dato il germe di un answer , ma solo il germe. La tecnica di base per convertire un valore in una stringa nel pre-processore C è in effetti tramite l'operatore '#', ma una semplice traslitterazione della soluzione proposta ottiene un errore di compilazione:

#define TEST_FUNC test_func
#define TEST_FUNC_NAME #TEST_FUNC

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

L'errore di sintassi si trova sulla riga 'put ()' - il problema è un '# randagio' nell'origine.

Nella sezione 6.10.3.2 della norma C, 'L'operatore #', dice:

  

Ogni # token di preelaborazione nel file   elenco di sostituzione per una funzione simile   la macro deve essere seguita da un parametro   come token di preelaborazione successivo nel file   elenco di sostituzione.

Il problema è che puoi convertire argomenti macro in stringhe, ma non puoi convertire elementi casuali che non sono argomenti macro.

Quindi, per ottenere l'effetto che stai cercando, devi sicuramente fare un lavoro extra.

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

Non sono del tutto chiaro su come prevedi di utilizzare le macro e su come prevedi di evitare del tutto la ripetizione. Questo esempio leggermente più elaborato potrebbe essere più informativo. L'uso di una macro equivalente a STR_VALUE è un linguaggio necessario per ottenere il risultato desiderato.

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

* Nel momento in cui questa risposta è stata scritta per la prima volta, il nome di shoosh ha usato 'Timido' come parte del nome.

Altri suggerimenti

@Jonathan Leffler: Grazie. La tua soluzione funziona.

Un esempio funzionante completo:

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

Esempio:

$ 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;
}

Riferimento: pagina C preprocessore di Wikipedia

#define TEST_FUN_NAME #FUNC_NAME

vedi qui

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top