Hacker News new | ask | show | jobs
by sharikous 1037 days ago
My philosophy on this is to treat C++ and C as completely different languages (as they actually are), like say Java and C or python and C. Yes it's nice that some part of the header file can be parsed in both languages and that most of the syntax is similar.

But once your expectation is that you have to do all the work at the FFI boundary it's less frustrating than to experience all the small mismatches as compiler errors or annoying runtime errors.

1 comments

As with all of the languages you mention, consuming C from the other language is trivial. And since C++ is a superset of C that is certainly true there. Consuming the other language from C is difficult without a C compatible runtime API to help bridge the gap.

Of course the issue for C++, unlike the other examples here, is that it does not have a runtime layer that can be used to bridge the gap. So we either write a wrapper in C++ using extern C, or use a tool to do it.

It seems there was a GSOC effort for SWIG to generate C wrappers for C++ libs but it might not have made it all the way? I don't see C as a target language on SWIG's site.

Still, a bespoke, high level design for the C wrapper is always going to be less painful for the consumer.

> And since C++ is a superset of C that is certainly true there.

C++ is not a superset of C. C99 has and C++ (at the time of writing) doesn't have: restricted pointers, designated initializers, variable length arrays, and probably more. These are language features that are actually used.

This doesn't change any of your core points.

> variable length arrays

It was such a terrible feature it was made optional in the C11 standard (you can be a conforming C11 compiler and not allow this feature) and will never, ever be implemented in a Microsoft compiler (while C is not a priority for MS, do note that they updated to C11 and C17).

You can hear their reasoning there :

https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-...

The linux kernel used to make use of the feature and removed every instance of it from the code base :

https://www.phoronix.com/news/Linux-Kills-The-VLA

> Particularly over the past several cycles there has been code eliminating the kernel's usage of VLAs and that has continued so far for this Linux 4.20~5.0 cycle. There had been more than 200 spots in the kernel relying upon VLAs but now as of the latest Linux Git code it should be basically over.

While I do agree that it is wrong to consider C++ a superset of C, it is time to forget about C99's biggest mistake and treat it as if it didn't happen.

Agreed completely on all counts.

Never ever use VLAs.

My point is really just semantic, the overall argument I was responding to is intact.

C++ has had designated initializers since c++20.
Point taken, I was inaccurate. Out of order designated initializers still don't work in C++20, right? Which still means C++ isn't a superset of C.
Any look into this will show that C's designated initializers are significantly more flexible/better in every way.
It’s amusing to me that whenever C has a feature that C++ doesn’t, C programmers hammer on the usefulness and power of said feature, but on the converse those same C programmers hammer on the divine simplicity of C.

C++ has constructors, it doesn’t really need designated initializers in the first place. They were added primarily for C compatibility.

> Of course the issue for C++, unlike the other examples here, is that it does not have a runtime layer that can be used to bridge the gap

neither, per standards, does c

Yes, but C is simple (and standard) enough that higher level runtimes have more or less universally managed to construct decent FFI mechanisms to access it.

C++ FFI would be kind of feasible if mangling were standardized (for instance) :-/

Standardizing name mangling would only be a baby step towards C++ ABI compatibility, sadly.