Мне известно 7 подходов:
1. Злоупотребление C ++ автоматическое typedef
s
(Обратите внимание, что структура должна быть объявлена во внутренней области видимости, чтобы она имела приоритет над внешним именем в C ++.)
char x;
{
struct x { char dummy[2]; };
printf("%s\n", sizeof (x) == 1 ? "C" : "C++");
}
Аналогичная версия, которая не зависит от неоднозначности между sizeof (type)
и sizeof (variable)
, используя только типы:
typedef char t;
{
struct t { char dummy[2]; };
printf("%s\n", sizeof (t) == 1 ? "C" : "C++");
}
2. Злоупотребление C ++ struct
/ class
эквивалентность, автоматическое typedef
s и автоматически сгенерированные конструкторы по умолчанию
/* Global*/
int isC = 0;
void Foo() { isC = 1; }
/* In some function */
struct Foo { int dummy; };
Foo();
printf("%s\n", isC ? "C" : "C++");
3. Злоупотребление вложенными struct
объявлениями в C
Также см. Столкновение символов внутренних и внешних структур, C ++ и C
typedef struct inner { int dummy; } t;
{
struct outer { struct inner { t dummy[2]; } dummy; };
printf("%s\n",
sizeof (struct inner) == sizeof (t)
? "C++"
: "C");
}
4. Злоупотребление //
комментарии
Это не будет работать с C99 или с компиляторами C89, которые поддерживают //
как расширение.
printf("%s\n",
0 //* */
+1
? "C++"
: "C");
или альтернативно:
printf("s\n",
1 //* */ 2
? "C++"
: "C");
5. sizeof
различия с char
литералами
Обратите внимание, что это не гарантируется переносимость, поскольку возможно, что некоторая гипотетическая платформа может использовать байты с более чем 8 битами, в этом случае sizeof(char)
может совпадать с sizeof(int)
. (Также см. Может ли sizeof (int) когда-либо быть 1 в размещенной реализации? )
printf("%s\n", sizeof 'a' == 1 ? "C++" : "C");
6. Различия в злоупотреблении при выполнении преобразования lvalue & rArr; rvalue
Это основано на примере 5.16, 5.17, 5.18 в стандарте ISO C ++ 03 и работает в gcc, но не в MSVC (возможно, из-за ошибки компилятора?).
void* array[2];
printf("%s\n",
(sizeof (((void) 0), array) / sizeof (void*) == 1)
? "C"
: "C++");
7. Злоупотребление различиями в том, как грамматики C и C ++ анализируют троичный оператор
Этот код не является строго законным, но некоторые компиляторы слабы.
int isCPP = 1;
printf("%s\n", (1 ? isCPP : isCPP = 0) ? "C++" : "C");
(Вы также можете проверить наличие макроса препроцессора __cplusplus
(или различных других макросов), но я думаю, что это не соответствует духу вопроса.)
У меня есть реализации для всего этого по адресу:
http://www.taenarum.com/csua/fun-with-c/c-or-cpp.c