C / C ++ # определить макрос внутри макроса? - PullRequest
6 голосов
/ 24 февраля 2012

Я бы хотел что-то вроде:

#define C_OR_CPP(C__, CPP__) #ifdef __cplusplus\
CPP__\
#else\
C__\
#endif

Возможно ли это? Может быть, какой-нибудь грязный хак с #include?

Причина: Я делаю заголовок, где структура использует переменную-член типа vector<stuff>*, но в C я хочу, чтобы она просто была void*, вы знаете.

1010 * ТИА *

Ответы [ 4 ]

11 голосов
/ 24 февраля 2012

В чем проблема с

#ifdef __cplusplus
#define C_OR_CPP(C, CPP) CPP
#else
#define C_OR_CPP(C, CPP) C
#endif

(оставляя имена с двойным подчеркиванием для реализации на замечание Френеля)

1 голос
/ 24 февраля 2012

AProgrammer уже дал вам правильный ответ, но ответ на «возможно ли» часть вопроса - нет.Расширение макроса не происходит до тех пор, пока не будут обработаны все директивы препроцессора, поэтому любой макрос, который раскрывается в #define или #ifdef, будет передан компилятору в виде обычного исходного текста, что приведет к его компиляции.

1 голос
/ 24 февраля 2012

Нет в C ++.Но вы можете

#ifdef __cplusplus
# define CPP
#else
# define C
#endif

Я полагаю, это просто патологический пример с вашей стороны.Также обратите внимание, что двойное подчеркивание зарезервировано для разработчиков библиотек (см. 17.6.4.3.2 Глобальные имена).

vector , но в C я хочу, чтобы оно просто было void , вызнать.

Итак, что говорит против такого решения, как

struct Foo {
  #ifdef __cplusplus
  ...
  #else
  ...
  #endif
};

, или что говорит против предоставления разных API для разных языков программирования?

0 голосов
/ 30 апреля 2013

Мой английский плохой, и я прошу прощения за языковые ошибки и опечатки, если таковые имеются.

Если #ifdef не должен переносить вызов макроса, есть решение, не столь изящное.

г ++ только: Вы можете попробовать это в отдельных случаях. Но если в a или b есть запятые, обходные пути все еще нужны. Он просто основан на том факте, что __cplusplus определен как «1» в среде C ++ и остается сам, а не -

#define SELECT1(a, b) a
#define SELECT__cplusplus(a, b) b
#define xcat(a,b)  a##b
#define concat(...) xcat(__VA_ARGS__)
#define C_OR_CPP(C, CPP) concat(SELECT, __cplusplus)(C, CPP)

C_OR_CPP(1, 2)

Другие среды Проверьте макрос __cplusplus: компилятор, соответствующий стандарту C ++, должен сгенерировать

 #define __cplusplus value 

и значение должно> = 199711L

...