How can you send data to another process (at the c++ language level only) - c++

Suppose you are developing two application (A and B).
How can you send some piece of information to B from A if you are only allowed to work at the c++ language level (that is including the standard libraries and STL) ?
Now Im thinking std::ofstream and std::ifstream could be a possible solution (albeit a crude one) ? - but what pitfalls is there and can they be avoided ? (how?).

You just cannot. Standard C++17 does not know about any kind of inter-process communication and does not know much about processes (except thru std::system whose behavior is not really specified). Some operating systems don't have any processes and some of them don't have files and some of them don't have pipes.
Read more about operating systems. I strongly recommend Operating Systems: Three Easy Pieces (which is freely available).
Of course, you can read and write a file, but the synchronization between the two processes should still happen (perhaps by running one after the other, in some operating system specific way, so running A then B, and how that exactly happens is OS specific)
Read that C++17 standard (e.g. the draft here) to check.
Some C++17 implementations might not even have any notion of process. You could have a fully compliant C++17 on some embedded system without any operating system dealing with processes.
My recommendation is to be pragmatical, and use some framework like Boost, Qt, ZeroMQ, or POCO (or old Berkeley sockets) which deals with processes and inter-process communication facilities; you'll likely to find a framework supporting the several OSes you really care about (AFAIK, all of Boost, POCO, Qt know about Linux, Windows, MacOSX and offer a common API abstracting them; but you could find some academic operating system which is incompatible with them; in practice, any framework targeting both Windows and POSIX should be practically enough).
With some curiosity, you may find an OS with a good C++17 implementation which has a very weird API (look into GNU Hurd for an example).
If your IPC facility is based on byte streams, look into text-based protocols (perhaps JSONRPC, SOAP, HTTP, ...). They are easier to code and most of them come with some C++ compatible library...
And with a few months of work and a lot of know how, you might even port a recent GCC or Clang to most other operating systems: they are careful to abstract the requirements on the OS in a clever way.
Remember, you could find OSes which don't even have any file system: look into CapROS or Contiki for some recent example, and look also inside tunes.org where interesting discussions related to your topic, in the past century, have been archived. But with some pain (my guess is a few months of work for a GCC or Clang expert), you'll be able to port a recent GCC or Clang to target it to obtain a C++17 cross-compiler targetting them.
IMHO, a C++ standard library which enables only to "open" one single "file" (supposedly named THEFILE) is conforming to the letter of the C++17 standard. AFAIK, you don't have any guarantee that std::ifstream or std::ofstream works successfully.
BTW, current processors are practically multi-core, so it makes a lot of sense to try running A and B in parallel and doing some IPC (in an OS specific way, perhaps abstracted by some framework or library).

Related

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.

Does C++ deprecate some parts of the Linux API?

I am in the middle of reading The Linux Programming Interface and Linux programming by examples. Both are very good books and explain Linux API very well. But quite often I find myself thinking that in real world projects I would prefer C++ standard library, Boost or some other good C++ library (there are many well written and portable C++ libs) over C API whenever possible. This naturally bags a question - why do I need to use Linux API directly when good C++ compiler and libs (Boost, TBB and etc) are available on target platforms? I guess the same could be said about Windows API too, but I don't know much about Windows system programing.
This is not new to C++. In C, there have been two ways to open files for a long, long time:
// Only on POSIX
int fdes = open("file.txt", O_RDONLY);
Or:
// Any hosted C environment, POSIX or otherwise
FILE *fp = fopen("file.txt", "rb");
So why would anyone ever use the POSIX-specific version? The answer is simple -- there are a large number of system calls which work with POSIX file descriptors. For example, select. You can also make things other than files, like pipes and sockets, and you can pass them to other processes. There is a long tradition of using POSIX file descriptors, and we have a large number of books and references on how to do network programming with them.
So the trade-off is between the portable version and the powerful version. It always has been.
The other half of this is that time you work with files on Linux you are working with the POSIX interface. Libraries just hide it from you. Boost uses it, the C runtime uses it, the JRE uses it, and GHC uses it. Many (most?) language runtimes are written in C, and direct access to the system calls is preferred.
You should use higher level API whenever possible. It's usually faster to work with and makes it easier to port your code to another platform. However:
Due to the law of leaky abstractions it's useful to know the underyling operating system API so you understand various quirks and performance issues that the higher level API was not able to hide.
Some things are not doable with the portable API, usually because it's so different between operating systems that it's not easily possible.
All portable APIs incur some overhead. In a big project it's small compared to the rest of the code, but if you are doing something small, you might want to avoid that overhead, especially if you know you'll need to use the specific API somewhere anyway.
C++ standard is not published for a particular platform. It is platform independent, So If you are going to use some platform features/functionality you will have to use platform dependent feature/functionality usually called system api. So in that sense No the C++ library does not deprecate linux/windows api.

are programs coded separately for different operating systems?

If a program was written in c++ to run on Windows, does it have to be completely rewritten to run on Mac OS or a mobile OS?
C++ is a standard language, which means that the source code that you write can be compiled on any platform which has an implementation of the C++ standard. There are two ways you can write C++ programs that can't be compiled on different implementation. First, if you use language extensions that are found on a specific (set of)implementation(s) only. Second, using a library that depends on code that doesn't ship with the standard library(like on OS API).
For the first matter, try always to write standard code. For the second, use cross-platform libraries like Boost, Qt...
Typically, yes, because the program will need to use OS-specific features for windowing and possibly for other features as well (networking, synchronization, etc.) However, many programs try to mitigate this as much as possible by building wrapper classes so that most of the program deals with these wrappers rather than the raw platform-specific tools. To port the program from one platform to another, you just need to reimplement the wrappers using the new platform's tools.
Many programs take this a step further by using prewritten libraries like Qt or Boost to handle some of the cross-platform silliness, but this is (essentially) the above idea at a larger scale.
This depends. In general, Standard C++ is a general-purpose, portable language which can be compiled to run on any system or platform that has a standard-compliant compiler.
However, a lot of the more "interesting" features you might want to add to a typical application are not part of Standard C++. This includes GUIs, threads, sockets, and low-level OS API calls. These are generally not portable, and parts of the code which use these features will need to be implemented separately for each operating system or platform.
Fortunately, this is not as daunting as it sounds, because there are a lot of cross-platform libraries in existence that have already gone through the trouble of doing this. For example, the Boost threading library already has threading code written for different platforms or operating systems, but all of this is abstracted behind a nice uniform API that can be used portably in C++ application code.
Additionally, a lot of non-Standard C++ code still conforms to some standard, such as POSIX, which is supported across multiple platforms. For example, most UNIX-ish systems, including Linux and Mac OS X, support POSIX threads (the pthread API).
If the code itself uses libraries that are supported on all the target platforms then you will only need the appropriate compilers to generate a valid binary for each system.
Software can be written in multiple languages and then linked together. For example, I can code the back-end logic of my application in C++ (often using Boost), and then build two separate front-ends in C# for Windows and Objective-C for Mac. I can link the C++ and C# components to ship for one platform, then link the C++ and Objective-C components to ship for another. That approach will give the most "native" look-and-feel for each platform.
As alternative, I can code the entire front-end in C++ using Qt or WxWidgets. This will run on all platforms, albeit without 100% of a platform's bells and whistles.

C++ thread/process identifier

Is there a portable way of getting thread and/or process identifier (string, int, ...) with C++?
You have a few ways, but all imply the use of an external library abstracting the thread for you.
Among the popular choices, two are:
The Boost.Thread library. This is the most portable but imply working with Boost, which is a HUGE library
The Qt library. This is less portable and imply to work with Qt, a big library.
If you already use any on these two libraries, I would recommend sticking with it. Otherwise, look at what other tools they provide and make a choice.
There is no portable way when portable means a way that works on every platform for that a C++ compiler exists. Such a way had to be part of the C++ standard, in which case it really would work everywhere (just like the other parts of the C++ standard work everywhere). Everything not in the standard is not guaranteed to work on any platform, unless the platform states to support this standard.
Every solution people have suggested here is a solution that uses an external library and thus can only work on platforms supported by that library; and no library is available for every existing platform.
Probably the one that will get you farthest is POSIX, after all every UNIX like system tries to support at least some POSIX (the more the better), very little can call themselves really being 100% POSIX-compliant platforms (e.g. A/UX, AIX, HP-UX, IRIX, Mac OS X 10.5, MINIX, QNX, Solaris, UnixWare, VxWorks, ... to name a few, there are more of course). However, there are quite a couple of platforms that offer at least some POSIX support, some more, some less and some are almost POSIX-compliant (e.g. FreeBSD, Linux, NetBSD, BeOS, OpenBSD, ... and others).
Windows is unfortunately far away from being one. NT used to be partly POSIX conform, but now it has more or less vanished (Win2000/20003, WinXP, and Vista can still be set into a POSIX emulating mode, translating some POSIX call to internal API calls by installing Microsoft Windows Services for UNIX - SFU 3.5 or higher), however there are ways to get some POSIX functionality on Windows through external libraries as well (Cygwin offers LGPL libraries you can link with your app to enable a fair amount of POSIX functions on Windows).
The advantage of POSIX is not only that it is relatively widespread, but also that it is standardized and you can easily look up the standard on the Internet. Using POSIX calls you can get a thread id and a process id.
I always thought threads were external from C++. In Java, there's a native thread built-in to the language.
You'd have to find a portable thread library.
The only way is to use portable library. Id recommend Qt (it doesn't have to be GUI app) or maybe wxWidgets. If you are developing a game check out SDL
Also check out boost libs they might have something.
You may also use part of ACE library, which implements a platform independent wrapper. Finding PID would be one of the files in the library (maybe ACE_Process/ ACE_Thread).
I'm not sure how portable they are but Posix threads may be another option you want consider. See also here. I agree with Steve's comment--portable to which platforms?
getpid() is a portable way to get the process ID.
I don't think you're going to find a portable method unless it is through a wrapper library. Each threading system (eg. Windows, or POSIX) are going to have their own mechanism.