I searched for lots of questions and answers, but I really couldn't figure out this issue. Yesterday I have tried C++11 thread on Windows in a Visual C++ project and it works fine.
Does that mean we can use C++11 threads on every platform that has a compiler with C++11 support? Are there any reasons not to use this thread instead of pthread or Windows thread (depending on the platform)?
The C++ 11 thread library still uses threads from the OS and relies on them but it is abstracted in a good way so you will experience almost no differences. The behavior is different only in the detail and you will almost not notice them (only on edge cases and/or on failure). There might be still some platforms out there which don't support everything from std::thread (even in 2015, e.g. on some specific / exotic mobile platforms).
From the C++ Standard:
30 Thread support library
Some functions described in this Clause are specified to throw
exceptions of type system_error (19.5.6). Such exceptions shall be
thrown if any of the function’s error conditions is detected or a call
to an operating system or other underlying API results in an error
that prevents the library function from meeting its specifications.
Failure to allocate storage shall be reported as described in
17.6.5.12.
C++11's thread mechanisms are intended to be cross-platform like any other feature of standard C++. From my understanding, all major compilers intend to support the C++ standard to the best of their ability which means supporting the threading library.
It really depends how well the compiler supports it. I would imagine GCC / VS /Intel have pretty good support by now but then if you are targeting some exotic platform that might not necessarily be the case.
That's been the case with the STL for a while now - it's mostly portable, but it really depends on the implementation.
Just because it's in the standard does not mean it will magically work, even though the chance of it working is much higher than if it was not in the standard.
There will still be other implementations - pthread, boost, whatever. Which one you use depends on your personal preferences, your requirements, etc, etc.
Yes, it is platform independent. It can be (and often is) implemented as wrapper for pthreads, so basically it can be pthreads with different API.
Related
With C++17 now published, even more of Boost's libraries are now covered by the standard library: optional, variant, any, ASIO (in the Networking TS), coroutines (in a TS) and more. This, in addition to the gobs and gobs of Boost stuff already in the standard, see this answer. I realize that some of the standardized versions have slightly different design space choices than Boost's, but essentially it's the same.
Given this fact, are there or have there been plans to release an alternative version (or just - a new mainline version) of Boost which:
Foregos most or all of these features as Boost libraries
Lets the rest of the Boost code rely on their availability in the standard library
Lets the Boost code rely on the language being at least C++17, to make life easier and the code more scrutable to developers
?
If not - is this because of the importance of the Boost design choices? Too much hassle? Fear of "project bifurcation"?
Note: This is an informative question, so please don't provide your opinion or whether this would be a good idea or not.
Boost has better implementation than many currently existing implementations of standard C++ library.
Note that:
Some issues might be fixed in the latest versions of compilers, I didn't recheck everything before writing this post.
Boost is quite conservative and support many old compilers. Even if the latest compiler has everything fixed, older version still have to work.
With regards to Unicode, I assume C++ programs will try to follow UTF-8 Everywhere.
Boost.Filesystem vs <filesystem>
Windows has no support for Unicode in both C/C++ runtimes e.g. you cannot switch standard library to Unicode-aware narrow character set (UTF-8). As the result std::filesystem::path always assumes non-unicode encoding when used with char sequences. There is std::filesystem::u8path for this, but writing std::filesystem::path p = some_char_sequence imo is way too easy. Any codebase that uses std::filesystem and supports Windows will have to battle this constantly.
Boost.Filesystem allowed user to specify locale to be used for path objects. Boost.Locale could be used to create UTF-8 locale on Windows, eliminating this issue. Std.filesystem does not allow you to do this.
Boost.System vs <system_error>
On Linux with glibc:
std::error_category::message is not thread safe, although it should be. Boost.System at least tries to provide thread-safe implementation for every platform.
System category is not able to test for equivalency with standard error conditions.
On Windows (MSVC) it is broken in multiple places:
Error messages returned by std::system_category have annoying "\r\n" at the end, which does not happen anywhere else. Boost.System explicitly trims those.
Comparing addresses of std::error_category does not work for generic and system categories if used cross-dll. Boost.System never had this issue.
Error message is returned using current user enconding (never UTF-8). Technically this is allowed since standard does not specify encoding used here, but it doesn't help anyone. Although Boost.System did the same (should not be mentioned here?).
Standard error categories are static-local singletons and thus register destructor through std::atexit. When category is accessed for the first time from another atexit handler. This might be a problem and can cause deadlocks (as any implicit locking). I had experience with this in the past.
System category is not able to match WinAPI error codes against POSIX error codes the same way Boost.System does this (something that was the whole point of this facility in the first place).
On MSVC12 (Visual Studio 2013) comparing error categories does not work across dlls. This is one of compilers supported by Boost. Boost.System had no such issues.
The sad part about <system_error> is that <filesystem> and future networking library (ASIO) both rely on it heavily, so both get a little bit broken on Windows.
Boost.Thread vs <mutex>, <condition_variable>, <shared_mutex>.
Until recently on Windows and MSVC std::condition_variable and std::mutex could cause deadlock when instantiated in a dll due to using lazy initialization internally. With MSVC14 (Visual Studio 2015) this should be fixed at least for std::mutex since it was rewritten to use SRW locks internally, but I am not sure about condition variables. MSVC12 (Visual Studio 2013) definitely has a lot of bugs here.
If you need a reader-writer lock, it might be very important to know if it favors readers or writers. Standard std::shared_mutex does not allow you to specify this behavior and according to the original proposal this was done because there is an algorithm that allows implementation to favor neither and try to prevent starvation of both (somewhat "fair" lock). Original implementation e.g. boost::shared_mutex follows this algorithm and is not based on pthread_rwlock_t (which usually favors readers due to requirements of POSIXas std::shared_mutex. Imo this means std::shared_mutex has a poor implementation on many systems. Although Boost implementation is not the fastest one either.
I work on large scale, multi platform, real time networked applications. The projects I work on lack any real use of containers or the Standard Library in general, no smart pointers or really any "modern" C++ language features. Lots of raw dynamically allocated arrays are common place.
I would very much like to start using the Standard Library and some of the C++11 spec, however, there are many people also working on my projects that are against because "STL / C++11 isn't as portable, we take a risk using it". We do run software on a wide variety of embedded systems as well as fully fledged Ubuntu/Windows/Mac OS systems.
So, to my question; what are the actual issues of portability with concern to the Standard Library and C++11? Is it just a case of having g++ past a certain version? Are there some platforms that have no support? Are compiled libraries required and if so, are they difficult to obtain/compile? Has anyone had serious issues being burnt by non-portable pure C++?
Library support for the new C++11 Standard is pretty complete for either Visual C++ 2012, gcc >= 4.7 and Clang >= 3.1, apart from some concurrency stuff. Compiler support for all the individual language features is another matter. See this link for an up to date overview of supported C++11 features.
For an in-depth analysis of C++ in an embedded/real-time environment, Scott Meyers's presentation materials are really great. It discusses costs of virtual functions, exception handling and templates, and much more. In particular, you might want to look at his analysis of C++ features such as heap allocations, runtime type information and exceptions, which have indeterminate worst-case timing guarantees, which matter for real-time systems.
It's those kind of issues and not portability that should be your major concern (if you care about your granny's pacemaker...)
Any compiler for C++ should support some version of the standard library. The standard library is part of C++. Not supporting it means the compiler is not a C++ compiler. I would be very surprised if any of the compilers you're using at the moment don't portably support the C++03 standard library, so there's no excuse there. Of course, the compiler will have to be have been updated since 2003, but unless you're compiling for some archaic system that is only supported by an archaic compiler, you'll have no problems.
As for C++11, support is pretty good at the moment. Both GCC and MSVC have a large portion of the C++11 standard library supported already. Again, if you're using the latest versions of these compilers and they support the systems you want to compile for, then there's no reason you can't use the subset of the C++11 standard library that they support - which is almost all of it.
C++ without the standard library just isn't C++. The language and library features go hand in hand.
There are lists of supported C++11 library features for GCC's libstdc++ and MSVC 2012. I can't find anything similar for LLVM's libc++, but they do have a clang c++11 support page.
The people you are talking to are confusing several different
issues. C++11 isn't really portable today. I don't think any
compiler supports it 100% (although I could be wrong); you can
get away with using large parts of it if (and only if) you limit
yourself to the most recent compilers on two or three platforms
(Windows and Linux, and probably Apple). While these are the
most visible platforms, they represent but a small part of all
machines. (If you're working on large scale networked
applications, Solaris will probably be important, and Sun CC.
Unless Sun have greatly changed since I last worked on it, that
means that there are even parts of C++03 that you can't count
on.)
The STL is a completely different issue. It depends partially
on what you mean by the STL, but there is certainly no
portability problem today in using std::vector. locale
might be problematic on a very few compilers (it was with Sun
CC—with both the Rogue Wave and the Stlport libraries),
and some of the algorithms, but for the most part, you can
pretty much count on all of C++03.
And in the end, what are the alternatives? If you don't have
std::vector, you end up implementing something pretty much
like it. If you're really worried about the presence of
std::vector, wrap it in your own class—if ever it's not
available (highly unlikely, unless you go back with a time
machine), just reimplement it, exactly like we did in the
pre-standard days.
Use STLPort with your existing compiler, if it supports it. This is no more than a library of code, and you use other libraries without problem, right?
Every permitted implementation-defined behaviour is listed in publicly available standard draft. There is next to nothing less portable in C+11 than in C++98.
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.
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.
With the advent of threading facilities in the STL for the new C++ standard (C++0x), will it be better to change existing code that is using POSIX threading or even Windows threading to use STL threading?
You could always hedge your bets... write your own simple threading API that is just featureful enough to do what your application needs to be done, and change your code to target your threading API only. Then you can implement the internals of your custom threading API using Windows or Posix or STL or whatever, and change the implementation whenever you need to without having to touch your entire codebase each time.
By doing it that way, you could start with the STL implementation, and then if it turns out that e.g. Windows has a difficult-to-resolve problem using that, you could just include an alternate Windows-API implementation inside my_threading_api.cpp (inside of an #ifdef WIN32) and you'd be back in business.
A great deal will depend on how much you care about portability, and how much you're taking advantage of features your native API may provide that the standard library doesn't. The standard library threading is sufficiently similar to POSIX that (at least offhand) I can't think of much you'd gain by staying with POSIX (and due to the similarity, porting to use the standard library should usually be pretty easy).
Windows threading is enough different that you're more likely to run into something that will be non-trivial to port to using the standard library, and even at best porting will probably be non-trivial.
Don't change unless you really need it. I assume that your existing code is working well.
There's no telling how long it will be before the C++0x library features are commonly supported, so the answer might well depend on how tied to a particular compiler you might want to be.
You might also want to consider a framework or library that works on top of the native or C++0x library implementation, such as Boost Threads or the Intel Threading Building Blocks and let that library handle the details of whether it's using C++0x features or platform APIs.
It depends.
C++0x threading isn't widely supported yet (I think GCC implements it, but MSVC doesn't, and I don't know when they're planning to add that support, but I might suspect they consider it a low priority feature)
If your code works as it is, why change it?
For new C++ applications, and assuming compiler support, I'd go with C++0x threads, simply because they're standard, and it's a much nicer API than either Win32 or POSIX threads.