Ecrire un programme qui sera imprimé « C » si compilé comme un (ANSI) programme C, et « C ++ » si compilé comme un programme C ++
-
19-09-2019 - |
Question
http://www.ocf.berkeley.edu/~ wwu / énigmes / cs.shtml
Il me semble très spécifique compilateur. Je ne sais pas où chercher?
La solution
Simple assez.
#include <stdio.h>
int main(int argc, char ** argv) {
#ifdef __cplusplus
printf("C++\n");
#else
printf("C\n");
#endif
return 0;
}
Ou bien est-il nécessaire de le faire sans la norme officielle?
Autres conseils
Nous avons dû faire une mission similaire à l'école. Nous ne pouvions pas utiliser préprocesseur (sauf pour #include
bien sûr). Le code suivant utilise le fait que dans C, les noms de type et les noms de structure forment espaces de noms distincts alors qu'en C ++, ils ne le font pas.
#include <stdio.h>
typedef int X;
int main()
{
struct X { int ch[2]; };
if (sizeof(X) != sizeof(struct X))
printf("C\n");
else
printf("C++\n");
}
Je sais que 7 approches:
1. Abus C ++ typedef
s automatique
(Notez que la structure doit être déclarée dans une portée intérieure de sorte qu'elle a la priorité sur le nom externe en C ++.)
char x;
{
struct x { char dummy[2]; };
printf("%s\n", sizeof (x) == 1 ? "C" : "C++");
}
Une version similaire qui ne repose pas sur l'ambiguïté entre sizeof (type)
et sizeof (variable)
, en utilisant uniquement des types:
typedef char t;
{
struct t { char dummy[2]; };
printf("%s\n", sizeof (t) == 1 ? "C" : "C++");
}
2. Abuse C ++ d'équivalence struct
/ class
, typedef
s automatiques, et des constructeurs par défaut générés automatiquement
/* Global*/
int isC = 0;
void Foo() { isC = 1; }
/* In some function */
struct Foo { int dummy; };
Foo();
printf("%s\n", isC ? "C" : "C++");
3. déclarations de struct
imbriqués les abus dans C
Voir aussi Symbole heurtant de struct intérieur et extérieur , C ++ vs 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. Abus commentaires //
Cela ne fonctionne pas avec C99 ou avec des compilateurs de C89 qui prennent en charge //
comme une extension.
printf("%s\n",
0 //* */
+1
? "C++"
: "C");
ou bien:
printf("s\n",
1 //* */ 2
? "C++"
: "C");
5. différences sizeof
avec littérales char
Notez que cela ne soit pas garanti d'être portable, car il est possible que certains plate-forme hypothétique pourrait utiliser octets avec plus de 8 bits, dans lequel sizeof(char)
de cas pourrait être le même que sizeof(int)
. (Voir aussi peut sizeof (int) jamais 1 sur un hébergé la mise en œuvre? )
printf("%s\n", sizeof 'a' == 1 ? "C++" : "C");
6. différences d'abus dans les conversions lorsque lvalue⇒rvalue sont effectuées
Ceci est basé sur des 5,16, 5,17, 5,18 exemple dans la norme ISO C de 03, et il travaille en gcc mais pas dans MSVC (peut-être à cause d'un bug du compilateur?).
void* array[2];
printf("%s\n",
(sizeof (((void) 0), array) / sizeof (void*) == 1)
? "C"
: "C++");
7. différences d'abus de la manière C et C grammaires de ++ parse l'opérateur ternaire
Celui-ci est pas strictement juridique, mais certains compilateurs sont laxistes.
int isCPP = 1;
printf("%s\n", (1 ? isCPP : isCPP = 0) ? "C++" : "C");
(Vous pouvez également vérifier la macro préprocesseur __cplusplus
(ou d'autres macros), mais je pense que ne suit pas l'esprit de la question.)
J'ai mises en œuvre pour tout cela à: http://www.taenarum.com/csua/ fun-with-c / c-ou-cpp.c
puts(sizeof('a') == sizeof(int) ? "C" : "C++");
Il suffit de regarder pour voir si les macros compilateur __STDC__
et de __cplusplus
sont définis.
Un mot, __cplusplus
.
Je suppose que l'intention est d'écrire quelque chose qui dépend des différences entre les langues elles-mêmes, non seulement des macros prédéfinies. Bien qu'il soit techniquement pas absolument garanti au travail, quelque chose comme ceci est probablement plus proche de ce qui est souhaité:
int main() {
char *names[] = { "C", "C++"};
printf("%s\n", names[sizeof(char)==sizeof('C')]);
return 0;
}
Pour ce que ça vaut la peine, voici une autre réponse:
char x[sizeof(char *)+2], y[1];
printf("%.*s\n", sizeof(1?x:y)-sizeof(char *)+1, "C++");
Vous pouvez essayer des directives de préprocesseur, mais peut-être pas ce qu'ils recherchent.