Write a program that will print “C” if compiled as an (ANSI) C program, and “C++” if compiled as a C++ program

こ雲淡風輕ζ 提交于 2019-11-27 01:42:31

问题


Taken from http://www.ocf.berkeley.edu/~wwu/riddles/cs.shtml

It looks very compiler specific to me. Don't know where to look for?


回答1:


Simple enough.

#include <stdio.h>
int main(int argc, char ** argv) {
#ifdef __cplusplus
printf("C++\n");
#else
printf("C\n");
#endif
return 0;
}

Or is there a requirement to do this without the official standard?




回答2:


We had to do a similar assignment at school. We were not allowed to use preprocessor (except for #include of course). The following code uses the fact that in C, type names and structure names form separate namespaces whereas in C++ they don't.

#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");
}



回答3:


I know of 7 approaches:

1. Abuse C++ automatic typedefs

(Note that the struct needs to be declared in an inner scope so that it takes precedence over the outer name in C++.)

char x;
{
    struct x { char dummy[2]; };
    printf("%s\n", sizeof (x) == 1 ? "C" : "C++");
}

A similar version that doesn't rely on the ambiguity between sizeof (type) and sizeof (variable), using only types:

typedef char t;
{
    struct t { char dummy[2]; };
    printf("%s\n", sizeof (t) == 1 ? "C" : "C++");
}

2. Abuse C++ struct/class equivalence, automatic typedefs, and automatically-generated default constructors

/* Global*/
int isC = 0;
void Foo() { isC = 1; }

/* In some function */
struct Foo { int dummy; };
Foo();
printf("%s\n", isC ? "C" : "C++");

3. Abuse nested struct declarations in C

Also see Symbol clashing of inner and outer structs, 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. Abuse // comments

This won't work with C99 or with C89 compilers that support // as an extension.

printf("%s\n",
       0 //* */
       +1
       ? "C++"
       : "C");

or alternatively:

printf("s\n",
       1 //* */ 2
       ? "C++"
       : "C");

5. sizeof differences with char literals

Note that this isn't guaranteed to be portable since it's possible that some hypothetical platform could use bytes with more than 8 bits, in which case sizeof(char) could be the same as sizeof(int). (Also see Can sizeof(int) ever be 1 on a hosted implementation?)

printf("%s\n", sizeof 'a' == 1 ? "C++" : "C");

6. Abuse differences in when lvalue⇒rvalue conversions are performed

This is based off of the 5.16, 5.17, 5.18 example in the ISO C++03 standard, and it works in gcc but not in MSVC (possibly due to a compiler bug?).

void* array[2];
printf("%s\n",
       (sizeof (((void) 0), array) / sizeof (void*) == 1)
       ? "C"
       : "C++");

7. Abuse differences in the way C and C++'s grammars parse the ternary operator

This one isn't strictly legal, but some compilers are lax.

int isCPP = 1;
printf("%s\n", (1 ? isCPP : isCPP = 0) ? "C++" : "C");

(You also could check for the __cplusplus preprocessor macro (or various other macros), but I think that doesn't follow the spirit of the question.)

I have implementations for all of these at: http://www.taenarum.com/csua/fun-with-c/c-or-cpp.c




回答4:


puts(sizeof('a') == sizeof(int) ? "C" : "C++");



回答5:


Here's the program:

#include <stdio.h>

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

And here is some nice reading on C and C++ differences.




回答6:


Just look to see if the __STDC__ and __cplusplus compiler macros are defined.




回答7:


One word, __cplusplus.




回答8:


I'm guessing the intent is to write something that depends on differences between the languages themselves, not just predefined macros. Though it's technically not absolutely guaranteed to work, something like this is probably closer to what's desired:

int main() { 
    char *names[] = { "C", "C++"};

    printf("%s\n", names[sizeof(char)==sizeof('C')]);
    return 0;
}



回答9:


For what it's worth, here's another answer:

char x[sizeof(char *)+2], y[1];
printf("%.*s\n", sizeof(1?x:y)-sizeof(char *)+1, "C++");



回答10:


You could try preprocessor directives, but that might not be what they are looking for.



来源:https://stackoverflow.com/questions/2038200/write-a-program-that-will-print-c-if-compiled-as-an-ansi-c-program-and-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!