Are Unix and Linux API headers compatible with C++? - 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.

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.

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:
https://unix.stackexchange.com/questions/27042/what-does-a-kernel-source-tree-contain-is-this-related-to-linux-kernel-headers
http://kernelnewbies.org/KernelHeaders

Related

Can we use the POSIX C libraries in c++?

I am new in the field of Linux system programming.I currently program in C and want to switch to c++.
Can we use all the functions defined in POSIX C libraries in c++ without any change ?
In principle you should be able to use any C API from C++; the language includes features to facilitate it, and most C library authors are aware that people want to do this and will take the appropriate steps. For the system programming interfaces specified by POSIX, C++ compatibility is an explicit design goal.
However, you may still encounter problems. In my experience, the most common problems are:
C API headers often dump hundreds of symbols into the global namespace. Some of those symbols may conflict with C++ library symbols, which will get you in trouble if you using namespace std (but you weren't doing that, right?)
C API headers often make heavy use of macros, including macro names that, yep, might conflict with C++ library symbols; std:: won't save you there.
Compiling your program in a strict conformance mode (e.g. -std=c++11 -D_XOPEN_SOURCE=700) may expose bugs in system headers. This is more likely to happen with C++ than C.
A small handful of the POSIX APIs have abnormal control-flow behavior that may interact poorly with C++ exceptions and destructors, depending on how thorough your C library implementor was about avoiding the problem. setjmp and longjmp are obviously a concern here (has anyone done a C library that implements those on top of DWARF-style exception handling?) but so are fork, setcontext and friends, pthread_cancel, pthread_cleanup_push, and probably a few others I can't remember off the top of my head. (I recall a giant, ultimately inconclusive argument between Ulrich Drepper and the GCC C++ guys back in 2004 or so about exactly how pthread_cancel should behave in the presence of destructors.)
If you go beyond POSIX, you may also have problems with:
Headers that don't bother to wrap all the declarations in an extern "C" block when compiled as C++, which means all the function names get mangled when they shouldn't have been, and the link fails.
Headers that don't even bother to stick to the intersection of C and C++. In the worst case, this can cause failures that don't manifest until the program is run. The most common instances of this are:
Blithely using some C++ keyword as a declared-name (e.g. int template;)
Assuming that void * is assignment compatible with other pointer types (e.g. that it is not necessary to cast the result of malloc)
Assuming that struct foo; does not define a typedef-name foo
Note that the headers specified by POSIX frequently contain system-specific extensions that have not been as carefully thought out as the POSIX interfaces themselves.
"Can we use all the functions defined in POSIX C libraries in c++ without any change ?"
Of course you can. Any c-style API can be used seamlessly in c++.

How to find Boost libraries that does not contain any platform specific code

For our current project, we are thinking to use Boost framework.
However, the project should be truly cross-platform and might be shipped to some exotic platforms. Therefore, we would like to use only Boost packages (libraries) that does not contain any platform specific code: pure C++ and that's all.
Boost has the idea of header-only packages (libraries).
Can one assume that these packages (libraries) are free from platform specific code?
In case if not, is there a way to identify these kind of packages of Boost?
All C++ code is platform-specific to some extent. On the one side, there is this ideal concept of "pure standard C++ code", and on the other side, there is reality. Most of the Boost libraries are designed to maintain the ideal situation on the user-side, meaning that you, as the user of Boost, can write platform-agnostic standard C++ code, while all the underlying platform-specific code is hidden away in the guts of those Boost libraries (for those that need them).
But at the core of this issue is the problem of how to define platform-specific code versus standard C++ code in the real world. You can, of course, look at the standard document and say that anything outside of it is platform-specific, but that's nothing more than an academic discussion.
If we start from this scenario: assume we have a platform that only has a C++ compiler and a C++ standard library implementation, and no other OS or OS-specific API to rely on for other things that aren't covered by the standard library. Well, at that point, you still have to ask yourself:
What compiler is this? What version?
Is the standard library implementation correct? Bug-free?
Are those two entirely standard-compliant?
As far as I know, there is essentially no universal answer to this and there are no realistic guarantees. Most exotic platforms rely on exotic (or old) compilers with partial or non-compliant standard library implementations, and sometimes have self-imposed restrictions (e.g., no exceptions, no RTTI, etc.). An enormous amount of "pure standard C++ code" would never compile on these platforms.
Then, there is also the reality that most platforms today, even really small embedded systems have an operating system. The vast majority of them are POSIX compliant to some level (except for Windows, but Windows doesn't support any exotic platform anyways). So, in effect, platform-specific code that relies on POSIX functions is not really that bad since it is likely that most exotic platforms have them, for the most part.
I guess what I'm really getting at here is that this pure dividing line that you have in your mind about "pure C++" versus platform-specific code is really just an imaginary one. Every platform (compiler + std-lib + OS + ext-libs) lies somewhere along a continuum of level of support for standard language features, standard library features, OS API functions, and so on. And by that measure, all C++ code is platform-specific.
The only real question is how wide of a net it casts. For example, most Boost libraries (except for recent "flimsy" ones) generally support compilers down to a reasonable level of C++98 support, and many even try to support as far back as early 90s compilers and std-libs.
To know if a library, part of Boost or not, has wide enough support for your intended applications or platforms, you have the define the boundaries of that support. Just saying "pure C++" is not enough, it means nothing in the real world. You cannot say that you will be using C++11 compilers just after you've taken Boost.Thread as an example of a library with platform-specific code. Many C++11 implementations have very flimsy support for std::thread, but others do better, and that issue is as much of a "platform-specific" issue as using Boost.Thread will ever be.
The only real way to ever be sure about your platform support envelope is to actual set up machines (e.g., virtual machines, emulators, or real hardware) that will provide representative worst-cases. You have to select those worst-case machines based on a realistic assessment of what your clients may be using, and you have to keep that assessment up to date. You can create a regression test suite for your particular project, that uses the particular (Boost) libraries, and test that suite on all your worst-case test environments. Whatever doesn't pass the test, doesn't pass the test, it's that simple. And yes, you might find out in the future that some Boost library won't work under some new exotic platform, and if that happens you need to either get the Boost dev-team to add code to support it, or you have to re-write your code to get around it, but that's what software maintenance is all about, and it's a cost you have to anticipate, and such problems will come not only from Boost, but from the OS and from the compiler vendors too! At least, with Boost, you can fix the code yourself and contribute it to Boost, which you can't always do with OS or compiler vendors.
We had "Boost or not" discussion too. We decided not to use it.
We had some untypical hardware platforms to serve with one source code. Especially running boost on AVR was simply impossible because RTTI and exceptions, which Boost requires for a lot of things, aren't available.
There are parts of boost which use compiler specific "hacks" to e.g. get information about class structure.
We tried splitting the packages, but the inter dependency is quite high (at least 3 or 4 years ago).
In the meantime, C++11 was underway and GCC started supporting more and more. With that many reasons to use from boost faded (Which Boost features overlap with C++11?). We implemented the rest of our needs from scratch (with relative low effort thanks to variadic templates and other TMP features in C++11).
After a steep learning curve we have all we need without external libraries.
At the same time we have pondered the future of Boost. We expected the newly standardized C++11 features would be removed from boost. I don't know the current roadmap for Boost, but at the time our uncertainty made us vote against Boost.
This is not a real answer to your question, but it may help you decide whether to use Boost. (And sorry, it was to large for a comment)

How portable IS C++?

In C++, if I write a simple game like pong using Linux, can that same code be compiled on Windows and OSX? Where can I tell it won't be able to be compiled?
You have three major portability hurdles.
The first, and simplest, is writing C++ code that all the target compilers understand. Note: this is different from writing to the C++ standard. The problem with "writing to the standard" starts with: which standard? You have C++98, C++03, C++TR1 or C++11 or C++14 or C++17? These are all revisions to C++ and the newer one you use the less compliant compilers are likely to be. C++ is very large, and realistically the best you can hope for is C++98 with some C++03 features.
Compilers all add their own extensions, and it's all too easy to unknowingly use them. You would be wise to write to the standard and not to the compiler documentation. Some compilers have a "strict" mode where they will turn off all extensions. You would be wise to do primary development in the compiler which has the most strictures and the best standard compliance. gcc has the -Wstrict family of flags to turn on strict warnings. -ansi will remove extensions which conflict with the standard. -std=c++98 will tell the compiler to work against the C++98 standard and remove GNU C++ extensions.
With that in mind, to remain sane you must restrict yourself to a handful of compilers and only their recent versions. Even writing a relatively simple C library for multiple compilers is difficult. Fortunately, both Linux and OS X use gcc. Windows has Visual C++, but different versions are more like a squabbling family than a single compiler when it comes to compatibility (with the standard or each other), so you'll have to pick a version or two to support. Alternatively, you can use one of the gcc derived compiler environments such as MinGW. Check the [list of C++ compilers](less compliant compilers are likely to be) for compatibility information, but keep in mind this is only for the latest version.
Next is your graphics and sound library. It has to not just be cross platform, it has to look good and be fast on all platforms. These days there's a lot of possibilities, Simple DirectMedia Layer is one. You'll have to choose at what level you want to code. Do you want detailed control? Or do you want an engine to take care of things? There's an existing answer for this so I won't go into details. Be sure to choose one that is dedicated to being cross platform, not just happens to work. Compatibility bugs in your graphics library can sink your project fast.
Finally, there's the simple incompatibilities which exist between the operating systems. POSIX compliance has come a long way, and you're lucky that both Linux and OS X are Unix under the hood, but Windows will always be the odd man out. Things which are likely to bite you mostly have to do with the filesystem. Here's a handful:
Filesystem layout
File path syntax (ie. C:\foo\bar vs /foo/bar)
Mandatory Windows file locking
Differing file permissions systems
Differing models of interprocess communication (ie. fork, shared memory, etc...)
Differing threading models (your graphics library should smooth this out)
There you have it. What a mess, huh? Cross-platform programming is as much a state of mind and statement of purpose as it is a technique. It requires some dedication and extra time. There are some things you can do to make the process less grueling...
Turn on all strictures and warnings and fix them
Turn off all language extensions
Periodically compile and test in Windows, not just at the end
Get programmer who likes Windows on the project
Restrict yourself to as few compilers as you can
Choose a well maintained, well supported graphics library
Isolate platform specific code (for example, in a subclass)
Treat Windows as a first class citizen
The most important thing is to do this all from the start. Portability is not something you bolt on at the end. Not just your code, but your whole design can become unportable if you're not vigilant.
C++ is ultra portable and has compilers available on more platforms than you can shake a stick at. Languages like Java are typically touted as being massively cross platform, ironically they are in fact usually implemented in C++, or C.
That covers "portability". If you actually mean, how cross platform is C++, then not so much: The C++ standard only defines an IO library suitable for console IO - i.e. text based, so as soon as you want develop some kind of GUI, you are going to need to use a GUI framework - and GUI frameworks are historically very platform specific. Windows has multiple "native" GUI frameworks now - the C++ framework made available from Microsoft is still MFC - which wraps the native Win32 API which is a C API. (WPF and WinForms are available to CLR C++).
The Apple Mac's GUI framework is called Cocoa, and is an objective-C library, but its easy to access Objective C from C++ in that development environment.
On Linux there is the GTK+ and Qt frameworks that are both actually ported to Windows and Apple, so one of these C++ frameworks can solve your "how to write a GUI application in C++ once that builds and runs on windows, apple mac and linux".
Of course, its difficult to regard Qt as strictly C++ anymore - Qt defines a special markup for signals and slots that requires a pre-compile compile step.
You can read the standard - if a program respects the standard, it should be compilable on all platforms that have a C++ standard-compliant compiler.
As for 3rd party libraries you might be using, the platform availability is usually specified in the documentation.
When GUI comes to question, there are cross-platform options (such as QT), but you should probably ask yourself - do I really want portability when it comes to UI? Sometimes, it's better to have the GUI part platform-specific.
If you are thinking of porting from Linux to Windows, using OPENGL for the graphical part gives you freedom to run your program on both operating systems as long as you don't use any system specific functionality.
Compared to C, C++ portability is extremely limited, if not completely unexisting. For one you can't disable exceptions (well you can), for the standard specifically says that's undefined behaviour. Many devices don't even support exceptions. So as for that, C++ is ZERO portable. Plus seeing the UB, it's obvioulsy a no-go for zero-fail high-performance real time systems in which exceptions are taboo - undefined behaviour has no place in zero-fail environment. Then there's the name mangling which most, if not every, compiler does completely different. For good portability and inter-compatibility extern "C" would have to be used to export symbols, yet this renders any and all namespace information completely void, resulting in duplicate symbols. One can ofcourse choose to not use namespaces and use unique symbol names. Yet another C++ feature rendered void. Then there's the complexity of the language, which results in implementation difficulties in the various compilers for various architectures. Due to these difficulties, true portability becomes a problem. One can solve this by having a large chain of compiler directives/#ifdefs/macros. Templates? Not even supported by most compilers.
What portability? You mean the semi-portability between a couple of main-stream build targets like MSVC for Windows and GCC for Linux? Even there, in that MAIN-STREAM segment, all the above problems and limitations exist. It's retarded to even think C++ is portable.

libstdc++-doc simply ignores imported c functions,c++ really junky?

Each header from the C Standard
Library is included in the C++
Standard Library under a different
name, generated by removing the .h,
and adding a 'c' at the start, for
example 'time.h' becomes 'ctime'. The
only difference between these headers
and the traditional C Standard Library
headers is that where possible the
functions should be placed into the
std:: namespace (although few
compilers actually do this).
Since c functions are put into the std:: namespace,I tried :
man std::printf
but got :
No manual entry for std:printf
Any reasons?(I've installed libstdc++-doc and I've no problem with canonical c++ stuff like man std::cout)
UPDATE
The reason to say c++ is junky at least includes:
junky c++ manual
an empty c++ programe needs libstdc++,libm and libgcc_s,while c programe only needs libc.
There really is no point in documenting the C++ functions that come from standard C if they are identical and are already documented (like printf is).
The behavior of the C standard library functions is out of the control of libstdc++ developers. It relies (in this and most other C++ Standard library implementations) on the underlying platform's Libc implementation. On Linux, that's most probably glibc, on Windows, msvcrt, etc...
The point is that all these different libraries provide different and non-conforming behavior, which would have to be documented in the libstdc++ documentation, and that is impossible (no, very hard) to do and maintain. It also serves no practical purpose, as this documentation exists elsewhere.

C++ Stdlib IO Implementation details

Are there any guarantees that C++ std IO will be portable across all Desktop and Mobile OS (I'm interested in iOS and Android)?
Is implementation of std IO different across the platforms or it is rather uniform? If it is different, then does it happen due to SDK of the platform (in other words - do SDK's provide those different implementations)?
Who provide those implementation? Who is the author? Does anybody update them?
Where is documentation?
Are there any guarantees that C++ std
IO will be portable across all Desktop
and Mobile OS (I'm interested in iOS
and Android)?
No, there are no guarantees that these platforms will implement, correctly at all the standard library.
Is implementation of std IO different
across the platforms or it is rather
uniform? If it is different, then does
it happen due to SDK of the platform
(in other words - do SDK's provide
those different implementations)?
It's different. I/O is very different on different platforms.
Who provide those implementation? Who
is the author? Does anybody update
them? Where is documentation?
Either the compiler implementor or the platform owner provides them. The C++ Standard describes what the library must do.
I think you are failing to see the power of the standard libraries. They are designed to provide a common set of functionality that is available across any standards compliant compiler. For example, if I write the following code:
#include <iostream>
int main(int a, char** s)
{
std::cout << "Hello World" << std::endl;
return 0;
}
This will be compiled by any standards compliant compiler. You're getting hung up on, well the way std::cout works is different on each platform - yes of course it is. But this is the beauty of it - why do you have to care? On windows, if you compile this with MS Visual C++, that compiler will have the correct implementation (which the standard doesn't care about) to support the above standard way of writing to standard out. Similarly, on Linux GCC will have the correct code to write to whatever implementation, and on Solaris, CC will do the same.
You don't have to worry or frankly care. The handling for your platform is provided by the compiler that you are using for that platform. You have a nice clean high-level interface to work with.
Do you care how the Java VM handles the details of each platform? You don't, it's not your concern, you know when you do System.out.println() it will be written to the screen (or whatever for that VM) appropriately. SO why are you getting hung up on this?
The thing you have understand is whether the compiler that you are using on the specific platform will provide all the functionality in the standard library (i.e. is it fully standards compliant or not) and if not, what's missing and how to work around it. The rest is frankly irrelevant!
As for if you don't like it, well pay for something like Roguewave - which frankly is pissing money away, but it's your money to piss away...
Standard library is exactly that — standard. It's defined by standard. Every standard-compliant compiler must provide it. So the guarantee is that it will be portable across standard-compliant implementations (whether there's one for your target platform is a whole different question altogether). It has nothing to do with platform SDKs (whether it's implemented using one doesn't matter — the observable behaviour must be the same).
The idea of a standard (hence the std) is that it is respected and uniform no matter what platform you are on.
Some developers ship devices with support for all or some of the std library, it's really just up to them how it is implemented.
This is platform specific and probably available in each platform's SDK documentation, available most probably with the SDK or on the vendor's website.