#define STR1 "s"
#define STR2 "1"
#define STR3 STR1 ## STR2
É possível concatenar ter STR3 == "s1"? Você pode fazer isso passando args para outra função Macro. Mas existe um caminho direto?
c++
c
c-preprocessor
tvr
fonte
fonte
Respostas:
Se forem as duas strings, você pode fazer:
O pré-processador concatena automaticamente as seqüências adjacentes.
EDITAR:
Como observado abaixo, não é o pré-processador, mas o compilador que faz a concatenação.
fonte
L"a"
e"b"
obterL"ab"
, mas pode concatenarL"a"
eL"b"
obterL"ab"
.Você não precisa desse tipo de solução para literais de cadeias, pois elas são concatenadas no nível do idioma e, de qualquer maneira, não funcionariam porque "s" "1" não é um token de pré-processador válido.
[Editar: Em resposta ao comentário incorreto "Just for the record" abaixo, que infelizmente recebeu vários upvotes, reiterarei a declaração acima e observarei que o fragmento do programa
produz essa mensagem de erro da fase de pré-processamento do gcc: error: colar "" s "" e "" 1 "" não fornece um token de pré-processamento válido
]
No entanto, para colar o token geral, tente o seguinte:
Então, por exemplo, ambos
PPCAT_NX(s, 1)
ePPCAT(s, 1)
produza o identificadors1
, a menos ques
seja definido como uma macro, caso em quePPCAT(s, 1)
produz<macro value of s>1
.Continuando com o tema estão estas macros:
Então,
Por contraste,
fonte
"s""1"
é válido em C (e C ++). São dois tokens (strings literais) que o compilador concatena a si próprio e ameaça como um token."s""1" isn't a valid token
- isso está correto; são, como você diz, dois tokens. Mas juntá-los com ## os tornaria um único token de pré-processamento, não dois tokens; portanto, o compilador não faria uma concatenação, e o lexer os rejeitaria (a linguagem requer um diagnóstico).STRINGIZE_NX(whatever occurs here)
expande para "o que quer que ocorra aqui", independentemente de quaisquer definições de macro para o que quer que ocorra, ou aqui.if A is defined as FRED then STRINGIZE_NX(A) still expands to "FRED"
- isso é falso e não é nada parecido com o seu teste. Você está se esforçando para não entender ou entender direito, e eu não vou responder mais a você.Dica: A
STRINGIZE
macro acima é legal, mas se você cometer um erro e seu argumento não for uma macro - você digitou um erro de digitação no nome ou esqueceu#include
o arquivo de cabeçalho -, o compilador colocará o nome da macro no campo string sem erro.Se você pretende que o argumento to
STRINGIZE
seja sempre uma macro com um valor C normal,irá expandi-lo uma vez e verificar sua validade, descarte-o e depois expanda-o novamente em uma sequência.
Levei um tempo para descobrir por que
STRINGIZE(ENOENT)
estava acabando, em"ENOENT"
vez de"2"
... eu não tinha incluídoerrno.h
.fonte
,
operador. :)((1),"1") "." ((2),"2")
vez de apenas "1" "." "2")STRINGIZE
definição original ,"The value of ENOENT is " STRINGIZE(ENOENT)
funciona, enquanto"The value of ENOENT is" STRINGIZE_EXPR(X)
produz um erro.