Write a program that will print “C” if compiled as

2020-02-03 06:14发布

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?

10条回答
狗以群分
2楼-- · 2020-02-03 07:14

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

查看更多
ら.Afraid
3楼-- · 2020-02-03 07:15

One word, __cplusplus.

查看更多
Juvenile、少年°
4楼-- · 2020-02-03 07:17

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");
}
查看更多
不美不萌又怎样
5楼-- · 2020-02-03 07:20
puts(sizeof('a') == sizeof(int) ? "C" : "C++");
查看更多
登录 后发表回答