Praxeolitic
Praxeolitic

Reputation: 24099

Are Unix and Linux API headers compatible with C++?

I have previously written C++ code that #includes Unix and Linux API headers and these programs have produced the expected behavior. That said, I don't know if this can be relied on. It's possible that incompatibilities between C and C++ could cause valid C headers to act in unexpected ways when used by C++ programs.

Can Unix and Linux API headers reliably be used by code that will be compiled as C++?

Is this a goal of the authors of those headers? Or are those headers only intended to be valid C?

Are there any known pitfalls when doing this?

Obviously the Unix and Linux distributions are numerous and I don't expect an answer to address every distribution one by one. My expectation is that the same answer will apply to almost all distributions of Unix and Linux and exceptions will prove the rule. If this assumption is wrong, an explanation of that would also be a valid answer.

By Unix headers I mean these:

http://www.unix.org/version3/apis/headers.html

By Linux headers I mean the headers provided by Linux distributions usually as a package named "linux-headers" that allow programs to interact with the Linux kernel. For example, this Debian package:

https://packages.debian.org/wheezy/kernel/linux-headers-3.2.0-4-amd64

I realize the Unix link is only a specification and that each Linux distribution is different but again I suspect it's reasonable to ask this question for most distributions. If that's not true then correct me.

Edit I only mean to refer to headers used by user space programs.

Upvotes: 3

Views: 437

Answers (2)

Nemo
Nemo

Reputation: 71565

C standard headers like <stdio.h>, <stdlib.h>, and so forth are specified in Appendix D of the C++ standard, which states:

These are deprecated features, where deprecated is defined as: Normative for the current edition of the Standard, but not guaranteed to be part of the Standard in future revisions.

The non-deprecated C++ versions of the C standard headers have names like <cstdio>, <cstdlib>, etc., and they technically put their definitions into the std (not global) namespace. So, to be 100% compliant with the non-deprecated part of the C++ spec, you need to write something like this:

#include <cstdio>

int main() {
  std::printf("Hello, world!\n");
}

That said, to my knowledge, no existing implementation actually forces you to do this, and in my opinion it is unlikely any ever will. So in practice, you can safely use C standard headers in C++ without much concern.

Also, if you are on (e.g.) a POSIX system, you can generally use POSIX functionality from C++ equally safely. Certainly nobody is going to deliberately break any of this because users would revolt.

However, accidental breakage is conceivable when mixing paradigms. If both the platform and the language standard provide some feature, you should use one or the other but not both. In particular, I would not mix POSIX threading and synchronization mechanisms with standard C++11 threading and synchronization mechanisms, because it is easy to imagine an optimizer knowing too much about the latter and generating code incompatible with the former.

[Update, to elaborate somewhat]

<unistd.h> is an example of what I mean about platform-dependent functionality. It will generally work fine from C++, and neither the library nor the compiler developers will break it gratuitiously because that would be too annoying. So go ahead and call getpid() or pipe() or whatever.

But be aware that mixing paradigms raises all sorts of questions. To name just a few off the top of my head:

  • Can you call new from a signal handler?
  • Can you use dup2 onto descriptor 0 to redirect cin?
  • What POSIX functions can you call safely during static initialization (i.e. before main executes)?

These questions and others like them are not addressed by any spec. The answers depend on your specific implementation and could change between releases.

Having said all that... Just about every non-trivial C++ program relies on platform-specific functionality exposed by some C interface. So what you are describing will work fine in practice provided you (a) have some idea what is going on "under the hood"; (b) have reasonable expectations; and (c) do not attempt to mix standard and platform-specific paradigms.

Upvotes: 6

paulsm4
paulsm4

Reputation: 121799

1) Yes: "standard headers" are standard. You can safely use them regardless of platform.

2) Yes: you can mix C headers (e.g. <stdio.h>) with C++ headers (e.g. <iostream>) in the same C++ translation unit.

3) NO: you should NOT use linux kernel headers in a user mode program, nor vice versa.

Linux kernel headers are intended for kernel-mode drivers, not for "normal", user space applications.

Here is a bit more information:

Upvotes: 0

Related Questions