Ecrire un programme qui sera imprimé « C » si compilé comme un (ANSI) programme C, et « C ++ » si compilé comme un programme C ++

StackOverflow https://stackoverflow.com/questions/2038200

  •  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?

Était-ce utile?

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 ++ typedefs 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, typedefs 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++");

Voici le programme:

#include <stdio.h>

int main(int argc, char *argv[])
{
    printf("This is %s\n", sizeof 'a' == sizeof(char) ? "C++" : "C");
    return 0;
}

est une lecture agréable sur les différences de C et 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top