Escapando um símbolo # em uma macro #define?
-
16-09-2019 - |
Pergunta
Sem entrar em detalhes sangrentos eu quero usar uma macro #define
que irá expandir a um #include
mas o sinal '#' é confuso o pré-processador (como ele pensa que eu quero citar um argumento.)
Por exemplo, eu quero fazer algo como isto:
#define MACRO(name) #include "name##foo"
E usá-lo assim:
MACRO(Test)
Qual será expandida para:
#include "Testfoo"
O sinal # humilde está causando o pré-processador para vomitar. MinGW me dá o seguinte erro:
'#' is not followed by a macro parameter
Eu acho que preciso para escapar do sinal #, mas eu não faria se isso é mesmo possível.
Sim, macros são realmente mal ...
Solução
Tanto quanto eu me lembro de você não pode usar uma outra diretiva de pré-nos definir.
Outras dicas
é possível inserir um hash token de no fluxo de sinal pré-processado. Você pode fazê-lo da seguinte forma:
#define MACRO(hash, name) hash include name
MACRO(#,"hello")
-expands a:
# include "hello"
No entanto , o padrão rejeita explicitamente qualquer outra análise de tal linha para a existência de directivas de pré-processamento [cpp.rescan]:
O resultado completamente macro-substituída pré-processamento seqüência token não é processado como uma directiva de pré-processamento mesmo que se assemelha a um.
O problema não está realmente recebendo um símbolo # na saída do seu pré-processador.
Aparentemente você deseja que o pré-processador para reanalisar o seu arquivo, para lidar com as directivas # include recém-criado como parte da expansão macro. Ele não funciona dessa forma. Se uma linha começa com #, é uma instrução para o pré-processador e interpretados. Se uma linha não começa com #, é apenas sujeito a transformação de pré-processamento, incluindo substituição de macro. Este é um teste uma vez por linha.
MACRO(Test)
não começa com #. Portanto, não é interpretado como um pré-processador diretiva; em vez disso é sujeita a regras macro substituição.
Isso ocorre porque o # tem um significado especial quando usado em uma macro.
# means quote the following token (which should be a macro parameter name)
## means concatenate the preceding and following tokens.
Na sua situação o # não é seguido por um símbolo adequado. Assim, em sua situação, temos de passar por um nível de engano:
#define QUOTE(name) #name
#define TEST(name) QUOTE(name ## foo)
#include TEST(scot)
Você não pode fazer isso. directivas de pré-processador são reconhecidas antes da expansão macro; se os expande macro em algo que se parece com um pré-processador diretiva, esta directiva não será reconhecido. O melhor que você pode fazer é criar uma macro para o nome do arquivo:
#define MACRO(name) "name##foo"
...
#include MACRO(Test)
Este pode trabalho (ele funciona para macros #define
regulares sem parâmetros, mas eu não testei com macros com parâmetros).
#define MACRO(name) <name##foo>
#include MACRO(Test)
#define HASH_SIGN #
BOOST_PP_CAT(HASH_SIGN, include)
#define PARAM_NAME Param
#define GETNAME_(a) #a
#define GETNAME(a) GETNAME_(a)
int Param;
printf("%s = %i\n", GETNAME(PARAM_NAME), PARAM_NAME);