tags:

views:

386

answers:

7

I am looking for more examples that compile under both C (any standard) and C++, but run differently. As an example, I found this in comp.lang.c, which produces 8 for C, and 512 for C++:

#include <stdio.h>

struct A { char block[8]; };

int main(void) {
    struct B {
        struct A {
            char block[512];
        } a;
    };

    printf("sizeof(struct A) = %lu\n",
        (unsigned long) sizeof(struct A));
    return 0;
}

Does anyone have any more examples of this, especially ones not using this particular trick?

+6  A: 
#include <stdio.h>

int main(void)
{
    printf("%d\n", sizeof('a'));
    return 0;
}

In C, this prints 4. In C++, it prints 1.

Adam Rosenfield
Yes, I was actually familiar with this trick, being that 'c' is an int in C, and a char in C++, but it's still good to have it listed here.
Sean
That would make an interesting interview question - especially for people that put c/c++ expert on their CVs
Martin Beckett
Kind of underhanded though. The whole purpose of sizeof is so you don't need to know exactly how large a type is.
Dana the Sane
In C the value is implementation defined and 1 is a possibility. (In C++ it has to print 1 as stated.)
Windows programmer
+2  A: 

I suppose anything using the __cplusplus predefined macro would be trivial, and cheating a bit.

Greg Hewgill
+4  A: 

An old chestnut that depends on the c compiler not recognizing c++ end-of-line comments...

...
int a = 4 //* */ 2
        +2;
printf("%i\n",a);
...
dmckee
So, that's only in C89 compilers, not modern ones...
Jonathan Leffler
dmckee
+2  A: 

The C++ Programming Language (3rd Edition) gives three examples:

  1. sizeof('a'), as @Adam Rosenfield mentioned;

  2. // comments being used to create hidden code:

.

int f(int a, int b)
{
    return a //* blah */ b
        ;
}

3) Structures etc. hiding stuff in out scopes, as in your example.

derobert
+2  A: 
struct abort
{
    int x;
};

int main()
{
    abort();
    return 0;
}

Returns with exit code of 0 in C++, or 3 in C.

This trick could probably be used to do something more interesting, but I couldn't think of a good way of creating a constructor that would be palatable to C. I tried making a similarly boring example with the copy constructor, that would let an argument be passed, albeit in a rather non-portable fashion:

struct exit
{
    int x;
};

int main()
{
    struct exit code;
    code.x=1;

    exit(code);

    return 0;
}

VC++ 2005 refused to compile that in C++ mode, though, complaining about how "exit code" was redefined. (I think this is a compiler bug, unless I've suddenly forgotten how to program.) It exited with a process exit code of 1 when compiled as C though.

brone
Your second example using exit, doesn't compile on gcc or g++, unfortunately. It's a good idea, though.
Sean
+2  A: 

Another one listed by the C++ Standard:

#include <stdio.h>

int x[1];
int main(void) {
    struct x { int a[2]; };
    /* size of the array in C */
    /* size of the struct in C++ */
    printf("%d\n", (int)sizeof(x)); 
}
Johannes Schaub - litb
+1  A: 

most of these are all semantical tricks. if you're looking for more substance, realize that many things in C are not meant to be done, or can be done more elegantly, in C++. Consider: memory allocations in C++ (use RAII), casts, arrays (use std::vector), strings (use std::string), containers (use STL), I'm sure you can find more.

Dustin Getz