7

Around the Internet I see libraries that claim to be written in portable C++, as if it was a (maybe unofficial) standard.

Is there a precise definition of what is portable C++, and if so, what is it ?

I'm not asking for common practices for writing portable code, but if there really is something we can call "portable c++".

foxesque
  • 590
  • 6
  • 12
  • 2
    Among others, code that doesn't use compiler-specific extensions nor relies on undefined behavior even if it works. –  Apr 17 '16 at 10:34
  • 4
    Code that adheres to the iso standard, does not use platform specific things like os calls or inline assembly for a certain cpu and can thus be compiled an run on any platform with a standards conforming compiler. – Unimportant Apr 17 '16 at 10:34
  • 1
    I guess the real question is what is "non-portable C++" :-) – Kerrek SB Apr 17 '16 at 10:36
  • https://en.wikipedia.org/wiki/Software_portability – phuclv Apr 17 '16 at 10:39
  • Code that uses platform-specific stuff but supports many common platforms may also be described as "portable" – M.M Apr 17 '16 at 10:42
  • Thanks @ all for answers. Seems that no, there is no precise definition (or unofficial standard) to call something "portable c++". It's more a collection of practices that will make the code hopefully as portable as possible. Can I ask here if using std::uint8_t and other std types like this is portable ? – foxesque Apr 17 '16 at 10:57
  • @renardesque `std::uint8_t` doesn't have to be available on every platform. – Leandros Apr 17 '16 at 11:02
  • So using these types is contrary to the advice that comes in every answer : use the standard library. Am I wrong ? Does it just boils down to including ? – foxesque Apr 17 '16 at 11:05

2 Answers2

10

Portable C++ is quite ambiguous.

However, if you want to achieve portability, only use the Standard Library of C++, and no platform specific code (like read, write syscalls on Linux), no compiler specific intrinsics (like GCC's C / C++ extensions), or inline assembly for a specific CPU.

Keep in mind, that even this might not be "portable". You can compile C++ for a wide variety of platforms (including embedded), and not all of these platforms might ship with a Standard C++ library, or have a compiler supporting the latest and greatest C++ features (C++11, C++14 comes in mind).

True portability can not be achieved, you can, however, achieve portability for the most common platforms, or commit to support these X platforms, and build a platform specific solution for each of them (which is a considerable amount of work, and results in a lot of #ifdef OS1 code).

Leandros
  • 16,805
  • 9
  • 69
  • 108
  • 2
    There's a big grey area here where portable *to other POSIX systems* might qualify. Windows is an odd bird. There's also some care and attention required to avoid compiler specific features. – tadman Apr 17 '16 at 10:34
  • Yes, true. POSIX is sort of portable on todays operating systems. Even for Windows (it still has a POSIX subsystem, even though it's old) and lot's of libraries to bridge POSIX calls to WinAPI calls (MinGW, Cygwin, etc). – Leandros Apr 17 '16 at 10:35
  • 1
    Isn't boost considered portable as well? I mean you don't *have* to limit yourself to the standard if the libraries claim portability. – default Apr 17 '16 at 10:41
  • 1
    @Default I wouldn't consider Boost portable, not even on todays most common platforms (where I include game consoles, mobile phones, etc). – Leandros Apr 17 '16 at 10:43
  • That is just why I added that I wasn't asking for portability practices. I just read Mozilla C++ Portability Guide, and they say NOT to use STL :) – foxesque Apr 17 '16 at 10:51
  • Yes, the STL is not really considered portable. – Leandros Apr 17 '16 at 10:54
  • I guess with STL you mean the Standard Template Library? Because it's a [wrong](https://stackoverflow.com/questions/5205491/whats-this-stl-vs-c-standard-library-fight-all-about/5205571#5205571) term to refer to the C++ standard library, and quite confusing too because I can't see what you mean when you say the latter is not portable. – edmz Apr 17 '16 at 11:05
  • @black Well, that's nitpicking on a very high level. But neither the C++ Standard Library, or the part which mimics the STL is portable. – Leandros Apr 17 '16 at 11:14
  • Again, I don't see points for asserting that; will you say what makes you say that? – edmz Apr 17 '16 at 11:45
  • @black Ever tried compiling / using the C++ standard library on a DSP, or any embedded system? As already said, true portability is nearly impossible to achieve. It all depends on what platforms you're concerned about. If embedded is not your target audience, and you only target, for example, Linux, you can safely assume the C++ standard library is in place and working. – Leandros Apr 17 '16 at 11:53
  • @Leandros The Standard guarantees portability (essentially, but it's not the appropriate term) on conforming implementations: It can't, of course, assure the same on non-conforming ones. IOW, it's not my fault. If my code targets hosted implementations, I must be able to use the "STL" - it doesn't matter whether it's a DSP or an embedded system. It's about conformance. Indeed, if I know I'm dealing with a freestanding environment, assuming the STL is wrong, as you say. – edmz Apr 17 '16 at 12:22
4

Portable C++ code means that such code can be compiled for (almost) any platform and by any implementation. So the goals are, it's unimportant if the program should be running on

  • different operating systems (windows, linux, OSX)
  • different architectures (x86, x86-64, titanium , sparc, arm)
  • different runtime libraries/compilers (gcc, clang, MSVC)

To achieve this, you have to consider many aspects - Don't use implementation defined APIs and behavior, only use the standard library - Don't use architecture defined assumptions and behavior, like that char has 8 bits, or negative integers are 2-complement and overflow or that int is 32-bit long and so on

Problem is, you often has to use stuff, for which there is no standard in C++, like networking interfaces. So libraries often try to work around this problem, by using different specific solutions for the most popular systems, selected by the preprocessor.

So as you see portability is always to see in a context, because absolute portability is not practical achievable. For example C++ code that is portable for any C++11 compliant compiler (but most compilers aren't 100%, see MSVC 12/2013), or portable for C++11 compliant compilers AND POSIX systems (so all unix systems can use it). And so on.

Superlokkus
  • 4,731
  • 1
  • 25
  • 57
  • Can you name a system that's still in use where `char` is not 8 bits? Is this even allowed in C++14? I know for historical reasons this could be just about anything, but in practice is that still the case? – tadman Apr 17 '16 at 10:47
  • @tadman I knew someone would bring this up, AGAIN. The C++ and C standards are not making any statement about the exact length of `char`, neither present nor future ones. For architectures were `CHAR_BIT != 8` see http://stackoverflow.com/a/6972551/3537677 – Superlokkus Apr 17 '16 at 10:51
  • That's a list of hardware so rare we should be more concerned about being hit by lightning or winning the Powerball Jackpot than ever having to write code for it. I was asking if there was anything common that we might not realize has a non-standard `char` size. Like if some embedded processors or DSPs do, for instance. – tadman Apr 17 '16 at 10:55
  • @tadman Maybe you don't write code for it, but it's not C++ standard compliant. Based on your logic, why don't use all that gcc or microsoft c++ extensions? I'm sorry sir, but your mindset is what I think leads to software that's hard to maintain and will soon depend on one compiler and also depends on idiocracy of legacy code. Also why didn't you just use stackoverflow?: http://stackoverflow.com/q/2098149/3537677 – Superlokkus Apr 17 '16 at 10:58
  • 1
    @tadman POSIX requires a byte to be an octet (8-Bit). And the C++ standard requires a char to be a byte. Therefore, every POSIX system is required to have a char as an octet. – Leandros Apr 17 '16 at 11:01
  • @tadman `char` is the size of a symbol/byte/character, and any system is free to specify for it self how many bits it needs for it. – Superlokkus Apr 17 '16 at 11:03
  • @Leandros Thank you for the clarification. I know it's enjoyed a long tradition of being 8 bits, but I wasn't sure what, if any, constraints were imposed upon it. – tadman Apr 17 '16 at 11:05
  • 1
    I don't know why this is even relevant for clean code. If you want an octet why don't you just use an `(u)int8_t`?! For what code do you have to make assumptions about the width of `char`?! – Superlokkus Apr 17 '16 at 11:08
  • @Superlokkus Something like that is worth putting into your answer as it does seem to be a reasonable concern. – tadman Apr 17 '16 at 11:17
  • @tadman I thought I had by saying "Don't use architecture defined assumptions and behavior, like that char has 8 bits...". This is only one thing out of many. – Superlokkus Apr 17 '16 at 11:48
  • It's better to say "don't do X, do Y instead" than "don't do X" with your reasoning unspecified. – tadman Apr 17 '16 at 11:50
  • 1
    @tadman Ananlog Devices SHARC DSP's have 32-bit char, Texas Instruments C5x series of DSPs have 16 bit char. Some audio dsp apparently have 24-bit chars. See also [this SO question](http://stackoverflow.com/questions/2098149/what-platforms-have-something-other-than-8-bit-char). – Ilya Popov Apr 17 '16 at 13:47