neither gcc nor clang are compliant with standard c++

25 points by raymii


lcapaldo

I have encountered a compiler that enforces this distinction. It was inconvenient, and “extern static” or “extern” in anonymous namespaces (so you could mention the C linkage so you could pass the function pointer to pthread_create say) tended to confuse tooling and people.

abbeyj

Not to worry, EDG has you covered: https://godbolt.org/z/vxEPb713e

aapoalas

With regards to C and C++ calling conventions, the one famous? infamous? "difference" is of course C++ classes! Let's say you're a C absolutist and will never write a single line in any other language, but want to interact with a C++-only library, maybe a dylib: that C++ library will almost certainly expose some functions that return non-POD class objects by-value:

// LibString has a copy constructor and destructor - it is non-POD.
class LibString;

class Foo {
  public:
    LibString toString() const;
}

What do you do? Here's your first attempt of binding Foo::toString:

// Let's say the LibString class internals look like this:
struct LibString {
  void *data_;
}

// Foo::toString
LibString _ZNK3lib3Foo8toStringE(Foo *this);


int main(int argc, char *argv[])
{
    Foo *this = newFoo(); // we had some constructor binding somewhere
    LibString result = _ZNK3lib3Foo8toStringE(this);
}

You run this and it segfaults. Damn! What's up with that? Well, you forgot about non-POD classes always being pass-by-reference. Here's what you should do instead:

// Foo::toString
LibString *_ZNK3lib3Foo8toStringE(LibString *out, Foo *this);


int main(int argc, char *argv[])
{
    Foo *this = newFoo(); // we had some constructor binding somewhere
    LibString result;
    LibString *result_ptr = _ZNK3lib3Foo8toStringE(&result, this);
}

Now things work, horrah!

I am not aware of any way that C make the struct LibString be automatically passed and returned by reference/pointer. Maybe that's for the best, since copy and move constructor and destructor questions will follow very soon after you've done this.

P.S. I've never really written a line of C in my life, so the above snippets are probably all wrong.