Pergunta

Por exemplo, é o seguinte possíveis:

#define definer(x) #define #x?
Foi útil?

Solução

Apesar de sua sintaxe é inválida, a resposta para a sua pergunta é tecnicamente sim.Mas ele só pode ser realizada por desagradável truques que fazem o código ilegível e unmaintainable.

Veja também: http://www.ioccc.org/years.html#1995_vanschnitz e http://www.ioccc.org/years.html#2004_vik2

Outras dicas

Não, você não pode fazer isso.
A libra (#) O símbolo tem um significado diferente em uma definição. Significa - se isso é um argumento, faça uma string citando.

Você não pode aninhar as diretivas de pré -processador C. Felizmente, quase nunca é necessário. Se você realmente precisa desse tipo de poder, quase certamente estará melhor com outro pré -processador que executa antes de entregar o código ao compilador C. Por exemplo:

sed 's/@CUSTOMER@/J. Random Person/' foo.c.in > foo.c
cc foo.c

Outro truque útil é isolar o truque em um único arquivo de cabeçalho, que é gerado por um programa que você escreve:

./generate-trickery --greet 'J. Random Person' > foo.h

onde foo.h vai parecer algo assim:

#define GREET(x) ("J. Random Person greets you, " #x)

Se você amarrar isso com um Makefile, ou alguma outra automação, será bastante perfeita e não tropeçará muito no seu desenvolvimento.

Não, você não pode fazer isso.

Você pode fazer referência a uma macro de outra, mas não pode definir uma macro de outra.

Se você está tentando criar um segmento de código pré -processador que possa ser chamado várias vezes para executar coisas ligeiramente diferentes, uma (moderadamente horrível) maneira que você pode fazer isso é isolar o código em um único .h arquivo que você então #include várias vezes. A ideia é que cada vez que você #include O arquivo que você está "chamando sua rotina" - você "passa argumentos" por primeiro #definecertas constantes de pré -processador a que o arquivo incluído se refere.

Um lugar onde eu vi que isso é útil é gerar enumerações "inteligentes" que podem converter para/a partir de seus formulários "stringizados" (que são úteis para E/S). Você cria um .h arquivo contendo por exemplo

ENUMVAL(foo)
ENUMVAL(bar)
ENUMVAL(baz)

e depois depois #include este arquivo duas vezes: uma vez onde ENUMVAL() é definido de forma a criar um enum declaração, e uma vez quando ENUMVAL() é definido de forma a produzir uma variedade de nomes de cordas. Ao fazer dessa maneira, você não precisa especificar a lista de tokens reais mais de uma vez.

#define definer(x) #define #x?

#x is a stringification of x. You can't #define a string token. (#define "foo".) It has to be an identifier [a-zA-Z0-9_]* token.

You can't nest #define's like that. You can't have a #define in a #define.

You can have #if's inside #if blocks.

#ifdef FOO

#ifdef BAR
 ...
#else // BAR
 ...
#endif // BAR

#else // FOO
 ...
#endif //FOO

You are also somewhat limited as to the expressions you can use in #if macros. But you can sometimes work around that. For example:

        /* Use CONCATENATE_4_AGAIN to expand the arguments to CONCATENATE_4 */
#define CONCATENATE_4(      a,b,c,d)  CONCATENATE_4_AGAIN(a,b,c,d)
#define CONCATENATE_4_AGAIN(a,b,c,d)  a ## b ## c ## d

    /* Creates a typedef that's legal/illegal depending on EXPRESSION.       *
     * Note that IDENTIFIER_TEXT is limited to "[a-zA-Z0-9_]*".              *
     * (This may be replaced by static_assert() in future revisions of C++.) */
#define STATIC_ASSERT( EXPRESSION, IDENTIFIER_TEXT)                     \
  typedef char CONCATENATE_4( static_assert____,      IDENTIFIER_TEXT,  \
                              ____failed_at_line____, __LINE__ )        \
            [ (EXPRESSION) ? 1 : -1 ]

Plus something like:

STATIC_ASSERT( sizeof(int1) == 1, sizeof_int1_equal_1 );

(Yes, I know about #include <stdint.h>. It's just an example.)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top