/ / Ucieczka z symbolu # w makrze #define? - c ++, c, makra, c-preprocesor, preprocesor-dyrektywa

Ucieknięcie symbolu # w makro #define? - c ++, c, makra, preprocesor c, preprocesor-dyrektywa

Nie wchodząc w szczegóły, chcę użyć #define makro, które zostanie rozwinięte do a #include ale znak „#” jest mylący preprocesora (jak myśli, że chcę zacytować argument)

Na przykład chcę zrobić coś takiego:

#define MACRO(name) #include "name##foo"

I używaj go w ten sposób:

MACRO(Test)

Który rozszerzy się na:

#include "Testfoo"

Skromny znak # powoduje, że preprocesor staje się barf. MinGW daje mi następujący błąd:

"#" is not followed by a macro parameter

Myślę, że muszę uciec od znaku #, ale nie jest to możliwe.

Tak, makra są naprawdę złe ...

Odpowiedzi:

28 dla odpowiedzi № 1

O ile pamiętam, nie możesz użyć innej dyrektywy preprocesora w definicji.


30 dla odpowiedzi nr 2

To jest możliwe wstawienie tokenów mieszania do wstępnie przetworzonego strumienia tokenów. Możesz to zrobić w następujący sposób:

#define MACRO(hash, name) hash include name
MACRO(#,"hello")

—Wyracza się do:

# include "hello"

jednakstandard wyraźnie wyklucza dalszą analizę takiej linii pod kątem istnienia dyrektyw przetwarzania wstępnego [cpp.rescan]:

Wynikająca z tego całkowicie zastępowana przez makro sekwencja tokena przetwarzania wstępnego nie jest przetwarzana jako dyrektywa przetwarzania wstępnego, nawet jeśli przypomina taką.


27 dla odpowiedzi nr 3

Problemem nie jest uzyskanie symbolu # na wyjściu preprocesora.

Najwyraźniej chcesz, aby preprocesor dokonał ponownej analizytwój plik, aby poradzić sobie z nowo utworzonymi dyrektywami #include w ramach rozszerzenia makra. Nie działa w ten sposób. Jeśli linia zaczyna się od #, to jest to instrukcja dla preprocesora i interpretowana. Jeśli linia nie zaczyna się od #, podlega tylko transformacji preprocesora, w tym podstawieniu makra. Jest to test raz na linię.

MACRO(Test)

nie zaczyna się od #. Dlatego nie jest interpretowany jako dyrektywa preprocesora; zamiast tego podlega regułom zastępowania makr.


10 dla odpowiedzi № 4

Dzieje się tak, ponieważ # ma specjalne znaczenie w makrze.

#  means quote the following token (which should be a macro parameter name)
## means concatenate the preceding and following tokens.

W twojej sytuacji # nie następuje właściwy token. Więc w twojej sytuacji musimy przejść przez poziom orientacji:

#define     QUOTE(name)     #name
#define     TEST(name)      QUOTE(name ## foo)

#include TEST(scot)

6 dla odpowiedzi № 5

Nie możesz tego zrobić. Dyrektywy preprocesora są rozpoznawane przed rozszerzeniem makra; jeśli makro zostanie przekształcone w coś, co wygląda jak dyrektywa preprocesora, dyrektywa ta nie zostanie rozpoznana. Najlepsze, co możesz zrobić, to utworzyć makro dla nazwy pliku:

#define MACRO(name) "name##foo"
...
#include MACRO(Test)

2 dla odpowiedzi № 6

To moc praca (działa normalnie) #define makra bez parametrów, ale nie testowałem ich z makrami z parametrami).

#define MACRO(name) <name##foo>
#include MACRO(Test)

0 dla odpowiedzi № 7
#define HASH_SIGN #
BOOST_PP_CAT(HASH_SIGN, include)

0 dla odpowiedzi № 8
#define PARAM_NAME Param
#define GETNAME_(a) #a
#define GETNAME(a) GETNAME_(a)

int Param;
printf("%s = %in", GETNAME(PARAM_NAME), PARAM_NAME);