<div dir="auto">Not to mention name mangling, since method names do not export as simple C function names. (Not unlike GHC’s Z-encoding.) I think the way that’s usually dealt with is to have a C wrapper and declare it as extern “C”?</div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, Oct 31, 2024 at 11:25 AM Ben Gamari <<a href="mailto:ben@smart-cactus.org">ben@smart-cactus.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hécate via ghc-devs <<a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a>> writes:<br>
<br>
> Hi devs,<br>
><br>
> Pardon me for the naïve question. I know that C++ FFI is *hard* in <br>
> Haskell. From the perspective of an end-user I have heard that `text`'s <br>
> new UTF-8 validation caused problems when released, as it relied on C++ <br>
> code, but I never had any problems with it personally. From the GHC  <br>
> perspective, what makes C++ a difficult language to interface with?<br>
><br>
There are a few reasons for this. First, there are considerations due to<br>
the language itself:<br>
<br>
 * C++ has an object system which our binding generators do not<br>
   currently make any attempt to capture. Consequently, developing<br>
   bindings to C++ libraries written in an object-oriented style can<br>
   require a fair amount of work.<br>
<br>
 * the prevalence of C++'s template system means that one may need to<br>
   generate one or more C++ snippets to instantiate an interface before<br>
   one can even begin thinking about binding to the interface. This can<br>
   be particularly tricky in libraries where you may want polymorphism<br>
   in the Haskell binding to be reflected in the C++ instantiation.<br>
<br>
 * Dealing with C++'s exception system requires great care when<br>
   developing bindings.<br>
<br>
 * The language itself is otherwise vast in scope, with numerous<br>
   features that don't play well with others. Thankfully, usually C++<br>
   library authors who intend for their work to be bound by others often<br>
   restrict themselves to easily-bound features in their outward-facing<br>
   interfaces.<br>
<br>
Perhaps more significantly, there are also a variety of practical<br>
considerations:<br>
<br>
 * there are three implementations of the C++ standard library in common<br>
   use today (libstdc++, libc++, MSVC). Determining which library should be<br>
   used on a particular platform, and subsequently *how* to compile/link<br>
   against it, is quite non-trivial (e.g. see #20010). The<br>
   `system-cxx-std-lib` meta-package introduced in GHC 9.2 was aimed<br>
   at improving this situation for Haskell packages by making GHC<br>
   responsible for determining this configuration in such a way that<br>
   users can easily depend upon.<br>
<br>
 * even once you have compiled your program, linking against the C++<br>
   standard library introduces a dynamic library dependency on most<br>
   platforms. This is problematic as C++ standard library availability<br>
   and installation path is not nearly as consistent as the C standard<br>
   library. This is particularly problematic on Windows, where dynamic<br>
   linking is already fraught and non-MSVC runtime dependencies are<br>
   not widely available (e.g. [1])<br>
<br>
 * Code generated by C++ compilers tends to use less-common relocation<br>
   types, uncovering new and exciting ways for GHC's RTS linker to crash<br>
   (e.g. see #21618)<br>
<br>
 * To make matters worse, C++11 introduced an ABI breakage to optimise<br>
   the representation of `std::string`. This was in the past a source of<br>
   linking failures due to linking differently-compiled objects into the<br>
   same library/executable. Thankfully most people have moved to the new<br>
   ABI at this point so it's rare to see this manifest in the wild<br>
   except when linking against ancient proprietary binaries.<br>
<br>
All-in-all, the difficulty is just death by a thousand cuts, often due<br>
to platform-dependent toolchain issues, many even entirely independent<br>
of Haskell.<br>
<br>
Does this help?<br>
<br>
- Ben<br>
<br>
<br>
[1] <a href="https://github.com/haskell/ghcup-hs/issues/745" rel="noreferrer" target="_blank">https://github.com/haskell/ghcup-hs/issues/745</a><br>
_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org" target="_blank">ghc-devs@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs" rel="noreferrer" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs</a><br>
</blockquote></div></div>