2

So I've seen some C libraries written so that they compile without any changes with a C++ compiler, for example Lua.

What are some advantages and disadvantages of doing this?

A few basic ones I see are:

Advantages:

  • library can be used with any C or C++ project with no extra effort (without using extern "C" for example).

Disadvantages:

  • Harder to maintain because you need it compile as both (involves things like extra casts which can hide bugs)
  • Either limit yourself to C/C++ (sacrificing things like flexible array members), or end up with non-standard C++.

But I'm sure there's more to consider than just the above advantages and disadvantages. What sort of cases would doing this be appropriate, instead of using either pure C or C++ for the library?

  • // Harder to maintain because you need it compile as both // is why open-source organizations usually have a well-maintained and well-resourced build farm to test each code change on a diverse collection of build environments, compilers and versions. The other disadvantages and concerns are all valid. – rwong May 10 at 3:17
  • @rwong I'm not saying you shouldn't test it in various environments etc. I more meant you have to do extra work in your code to compile it as both (adding extra casts that you wouldn't need in C for example). – CoffeeTableEspresso May 10 at 17:28
9

Well, there are many disadvantages:

  1. You cannot write good, idiomatic C, as it must also be valid C++.
  2. Dito for C++, but worse.
  3. Maintainers need to know C, and all the differences to C++. That is in effect a different third composite-language featuring the disadvantages of either plus all incompatibilities.
    I wonder if there is any good documentation for that? Especially as every combination of C version and C++ version is a different challenge.
  4. If you use multiple languages, you have to compile it as C and include it within a manually added extern "C"-block anyway.

Why not simply write it in whatever language you want, featuring a C-interface, and optionally adding a C++ facade on top of it for ease of use?

  • david.tribble.com/text/cdiffs.htm and en.wikipedia.org/wiki/Compatibility_of_C_and_C%2B%2B do a pretty good job of covering the differences. Note that most compilers will support basically all C features as an extension when compiling with C++ (which makes C++ almost a superset of C when compiling with these compilers). – CoffeeTableEspresso May 9 at 20:27
  • @CoffeeTableEspresso Yes, david tribble's text seems quite good for listing differences between C99 and C++98. But while the first is still often used, the two decades really make a difference for C++. The wikipedia text even on cursory reading seems a bit biased in favor of C++ and plain incorrect in many important points. – Deduplicator May 9 at 21:07
  • Is there really much difference between "idiomatic C" and "idiomatic C modified just enough to make it also valid C++"? Casting the result of malloc is one. – immibis May 9 at 22:09
  • 2
    How does writing in idiomatic C and then writing a C++ wrapper to contain the weirdness (or vice versa) stack up? – Dan Neely May 9 at 23:02
  • @immibis you lose things like flexible array members and designated initializers, which are very very important for writing idiomatic C. It's not just the casts. – CoffeeTableEspresso May 9 at 23:38
1

A major advantage:

The authors only have to support one version of the code

  • 3
    This is possible when compiling exclusively as C or C++; some work may need to be done to support wrappers, but it is definitely still “one version of the code.” – gntskn May 10 at 0:07
1

The point is - why would anyone do it?

This is a lot of effort for what would ultimately be hard to maintain code which is not good C or C++.

Point in case: error conditions. C++ uses exceptions while C does not support them.

Write a C library, add an ifdefed extern "C" in the header and that's it. Add a separate C++ wrapper.

1

What sort of cases would doing this be appropriate, instead of using either pure C or C++ for the library?

When you expect that there will be

  • users of your library
  • on a platform that doesn't have both a C compiler and a C++ compiler, which each produce object files compatible with the other
  • wishing to write programs using the language you didn't.

Otherwise you should give C to C compilers, and C++ to C++ compilers.

0

Advantages compared to what?

You can compare it to "write a C library". Assume you have a library that is written in C, without care for C++.

You can just run it through a C++ compiler. You'll have to make a few changes, if you happened to name a variable "class" or "template". You'll have to make a few more changes because type checking may be stricter in C++. You may have to make a few casts for the results of malloc or the arguments to free. The last item, some people will tell you it's not idiomatic C - because it might hide the fact that you missed including some header file. That's not a valid fear today.

I think all in all it will make your code better, at quite little cost.

  • 3
    I think you overestimate the compatibility of C and C++. You have to add a cast for every malloc, and you lose very nice C features like flexible array members and designated initializers. The stricter type checking is of course much nicer in a lot of cases (such as with enums), but most people turn on stricter type checking when writing pure C anyways. – CoffeeTableEspresso May 9 at 20:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.