Why does C provide language ‘bindings’ where C++ falls short?

I recently was wondering when to use C over C++, and vice versa? Fortunately someone already beat me to it and although it took a while, I was able to digest all the answers and comments to that question.

However one item in that post keeps being addressed again and again, without any kind of example, verification or explanation:

“C code is good for when you want to have multiple language bindings for your library”

That’s a paraphrase. I should note that several people point out that multiple language bindings are possible in C++ (via some extern functioning), but nevertheless, if you read that post in its entirety, it’s pretty obvious that C is ideal for portability/language binding. My question is: why?

Can someone please provide concrete reasons why writing libraries in C allows for easier bindings and/or portability in other languages?

8

C has a much, much simpler interface, and its rules for converting a source code interface into a binary interface are straightforward enough that generating external interfaces to bind to is done in a well-established manner. C++, on the other hand, has an incredibly complicated interface, and the rules for ABI binding are not standardized at all, neither formally nor in practice. This means that pretty much any compiler for any language for any platform can bind against an external C interface and know exactly what to expect, but for a C++ interface, it’s essentially impossible because the rules change depending on which compiler, which version, and which platform the C++ code was built with.

In C, there’s no standard binary language implementation rules,
either, but it’s an order of magnitude simpler and in practice
compilers use the same rules. Another reason making C++ code hard to
debug is the above-mentioned complicated grammar, since debuggers
frequently can’t deal with many language features (place breakpoints
in templates, parse pointer casting commands in data display windows,
etc.).

The lack of a standard ABI (application binary interface) has another
consequence – it makes shipping C++ interfaces to other teams /
customers impractical since the user code won’t work unless it’s
compiled with the same tools and build options. We’ve already seen
another source of this problem – the instability of binary interfaces
due to the lack of compile time encapsulation.

— Defective C++

11

If you’re trying to communicate with a speaker of another language, pidgin is easier than Shakespearean English.

C’s concepts – function calls, pointers, NULL-terminated strings – are very straightforward, so other languages can easily implement them well enough to call C functions. For historical reasons, many other languages are implemented in C, which makes calling C functions even easier.

C++ adds quite a bit of stuff – classes, with inheritance and vtables and access modifiers; exceptions, with stack unwinding and changing the flow of control; templates. All of this makes it harder for other languages to use C++ bindings: at best, there’s more “glue” or interoperability code to implement, and at worst, the concepts don’t translate directly (due to differences in class models, exception handling, etc.). For templates in particular, simply using (instantiating) them typically requires a compilation step with a C++ compiler, which vastly complicates using them from other environments.

With all of that said, it’s possible to overstate the difficulty of providing bindings from a C++ library to another language:

  • C++ bindings can be just as compatible as C, if you’re willing to work at it. As @DeadMG points out, C++ supports extern "C", so you can export C-style language bindings (with all of the simplicity and compatibility of C bindings) from a C++ library (with the limitation that you can’t expose any C++-specific functionality).
  • Another common objection to C++ language bindings is the lack of ABI stability for C++, but this too is overstated; C++ ABIs are less standardized than C ABIs, but standards and de facto standards do exist (the Itanium C++ ABI, which is also used on OS X; GCC’s de facto standard for Linux). Windows is worse, but even on Windows, staying within one Visual C++ version should work fine.

2

C is one of the oldest languages still around. Its ABI is simple, and virtually every operating system still in use today has been written in it. While some of those OS’s may have added stuff e.g. in C#/.NET or whatever on-top, down below they’re very much steeped in C.

That means that, in order to use the functionality provided by the OS, virtually every programming language out there needed a way to interface with C libraries anyway. Perl, Java, C++, they all natively provide ways to “talk C”, because they had to if they didn’t want to reinvent every single wheel there is.

This makes C the Latin of programming languages. (How many years of internet before that metaphor has to be “the English of progamming languages”?)


When you are writing your library in C, you get a C-compatible interface for free (obviously). If you are writing your library in C++, you can get C bindings, via extern "C" declarations as you mentioned.

However, you can get those bindings only for functionality that can be expressed in C.

So your library API cannot make use of…

  • templates,
  • classes,
  • exceptions,
  • any functions taking or returning objects.

One simple example, you would need to make your exported functions take and return arrays ([]) instead of std::vector (or std::string for that matter).

So, not only would you be unable to provide any of the good things C++ has to offer to your library’s clients, you also would have to go to additional effort to “translate” your library API from C++ to “C compatible” (extern "C").

That is why the point could be made that C is the better choice for implementing a library. Personally, I think the benefits of C++ still outweigh the necessary effort for a extern "C" API, but that’s just me.

7

Leaving out the details other answers already provide:

The reason so many languages provides a C binding is that all *nix and Windows operating systems expose most of their OS API via a C interface. So the language implementation already needs to interface with C to be able to run on the major Oses. Therefore, it is straightforward to also offer directly communicating with any C interface from the language itself.

There is no reason. If the semantics you’re trying to express are fundamentally C-compatible and not something like templates, there is no reason you can bind easier if the implementation is written in C. In fact, it’s pretty much by definition that a C interface can be filled out by any implementation that can meet the binary contract- including an implementation in another language. There are languages other than C++ that can implement C binary contracts that can work in this fashion.

What it really boils down to is people who don’t want to learn new languages or ideas that have actually useful semantics or features desperately trying to pick any reason to stay in the dinosaur era.

7

There are two major axes when interfacing with another language:

  • the concepts that the interface can carry over: just values? references? generics?
  • how the interface is implemented in “binaries” (called ABI)

C has an advantage over C++ on those two fronts:

  • C only has mostly simple concepts, which appear in most every other language1
  • The ABI of C binaries is decided by the OS2

Now, why do most languages have a similar set of concepts than C may be due to it either being “simple” or “pre-existing”; it does not matter though, the point is that they do.

On the contrary, C++ has complex concepts, and the ABI is decided by each compiler (though many adhere to the Itanimum ABI, except on Windows…). There was actually a proposal by Herb Sutter to have OSes fix a C++ ABI (on a per OS basis) to partially address this issue. Also, one should note that a C++ FFI is possible, D is attempting it3.

1 Except variadics (...), those are not simple

2 Does C have a standard ABI?

3 Interfacing D to Legacy C++ code

Fundamentally it comes down to the ABI standardisation. While neither C nor C++ has a standardised ABI that other languages can use to interface between binaries written, C has become a de-facto standard, everyone knows it and everyone else can use the same, simple, rules that the language has with respect to types and function calls.

C++ could have a standard ABI, but Stroustrup has said that he doesn’t see the need for one. He also says it would be difficult to get consensus from compiler writers (though I doubt that – the C++ standard committee would issue a ABI similar to existing ones and compiler writers would simply alter the next version of their compilers, which are occasionally incompatible with binaries built with old versions of their compilers anyway – I recall recompiling a couple of libraries with a new Sun compiler and finding they failed to work with the old ones)

You’ll note that that some companies have moved to using a standard ABI, Microsoft started this process with COM way back in the 90s, and today they’ve refined this into the WinRT ABI (not to be confused with the other WinRT that refers to a type of table OS) that allows programs written in C# to communicate with libraries written in C or C++ (ie Microsoft’s own OS layer is written in C++, exposed using WinRT and consumed by C# applications when they call any OS runtime routine)

There’s not a lot anyone can do unless a standards body steps up and fixes this situation. Microsoft obviously sees the value in it and has taken steps to resolve it for their platform.

So the answer is really C doesn’t provide language bindings. It happens that nobody has listened and consumes them regardless.

All answers fall short of the real problem: C++ compiling introduces “name mangling”, so binaries are incompatible with “simple” function calls.

All ABI stuff is little more than an attempt to standardize it.

In general it’s not guaranteed you can cross-link functions compiled with different compilers, even if you stick to plain C++. Formerly it was sure they were incompatible, but nowadays standardization is creeping in 😉

OTOH C was designed precisely to be a “high level Assembly” and allow all sort of easy interfacing.
It should not surprise it’s better suited to cross-language liking.

Side note: original C++ compiler (cfront) actually produced C source that had to be compiled, exactly like gcc that produces Assembly “under the hood”.

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật