Are there Visual C++ runtime implementations for other platforms? - c++

Does Visual C++ runtime imply Windows platform? I mean if I write a program that only directly uses functions specific to VC++ runtime and doesn't directly call Windows API functions can it be recompiled and run on any OS except Windows? I don't mean on Windows system emulator, I mean a ready implementation of VC++ runtime for some other OS.

The Visual C++ runtime contains the standard C++ library and platform specific auxiliary functions.
The Windows API is part of the Windows SDK, and is not included in the Visual C++ runtime.
When you compile a C++ program on a different platform you will use that platform's C++ library implementation.
I mean if I write a program that only directly uses functions specific to VC++ runtime and doesn't directly call Windows API functions can it be recompiled and run on any OS except Windows?
As long as you only use standard C++ functions and classes, yes.
I don't mean on Windows system emulator, I mean a ready implementation of VC++ runtime for some other OS.
The runtime itself is only available on Windows, as the implementation is very platform specific. As I have mentioned above, you only get source level compatibility and only if you don't use MS specific functions.

The "VC++ Runtime" refers to Microsoft's implementation of the standard C and C++ libraries on top of Windows, so yes, in that sense it does imply the Windows platform. (In fact, it's implemented in terms of the Win32 API since the OS needs to support all of those great things the standard library can do for you).
However, since it's just the implementation of the standard libraries for the C and C++ languages, as long as you're careful to write portable code (don't assume type sizes, don't use platform/compiler specific extensions to the standard, beware of functions with differing names/arguments, etc. etc. etc.), you should be able to recompile it for any platform that has a C/C++ standard library implementation available.

These are two different questions. If you stick to portable parts of C and RTL, you can of course recompile for a different platform - I do that on daily basis. But a VC++-generated executable can only be run on Windows - it's a Windows executable :)
However, don't assume that the whole VC++ runtime library is portable. Some functions are (strlen() for example), some exist but are named differently (strnicmp()), some are simply absent on other platforms.

I mean if I write a program that only directly uses functions specific to VC++ runtime and doesn't directly call Windows API functions can it be recompiled and run on any OS except Windows?
If by "functions specific to VC++ runtime" you mean standard library functions, then the answer is yes (but with some caveats)
If you mean non-standard functions that are in the VC runtime but aren't standard, like _snprintf(), then the answer is generally no (but other implementations might support them so you might be able to get away with it).
The caveats from the 1st answer are that your program might take advantage of implementation specific (or even unspecified or undefined) behavior that might make it not work the same on a different platform, even if your program uses nothing but standard library functions. In most cases these issues won't be a problem, but they are something to take into consideration when writing code that you want to be portable.

Once upon a time it was possible (Visual C++ 4.x?) to target Mac (68000 processor) with MFC/Visual C++, but that project has been abandoned for a long time.
Microsoft Mobile/Smart Device is some sort of cross development supported in the latest version of Visual Studio.

Related

Is it crucial to know by which compiler a specific binary generated in C++?

I want to know if it is important to know which compiler was used to compile a specific library in C++? Because I heard about ABI compatibility and I am curious to know if it does matter or not!
For example can I download binaries of OpenCV (including dlls and libs) for Windows which were compiled with MSVC and use them in another code which is compiled with MinGW?
It depends:
If a library's interface is C++-based, it will need to match the C++ ABI of the compiler the user of the library is using. This usually means that the user needs to be using the same compiler with a close version number.
If the library exposes only a "flat" C-based interface, even if it's internally written in C++, it only needs to match the C ABI of the compiler that the user of the library is using. The C ABI is usually defined by the platform and common across compilers.
Note that a "flat" interface could be "reconstituted" into a C++ class-based interface using "wrapper" classes defined in headers. In this case, as long as the library binary only exposes C-compatible functionality, it will still only be dependent on the C ABI.
Additionally as an aside, on Windows only, there is functionality called "COM" which provides a standard ABI to allow programs to use objects written using different compilers and even different languages entirely. However, COM classes are not ordinary C++ classes and their creation and use is quite different.
In the specific case of OpenCV, I've never used it but, looking at the filename of the download of the latest version "opencv-4.1.1-vc14_vc15.exe"; this indicates that it contains libraries for use with Microsoft's Visual C++ compiler versions 14 and 15 (aka Visual Studio 2015 and 2017). If you want to use it with MinGW (which uses the GCC compiler) then you'll need to get an unofficial build or compile it from source yourself.

C++ Using features of a newer compiler to generate code for use by an older compiler

I've been looking into some of the features of the "newer" C++ standards (C++11 and C++14), and that got me thinking about something. I'm currently using the VC++2008 compiler for my projects (for various reasons), which means that the newest standard I have access to is C++03, plus TR1. TR1 has some nice things in it, but there are features in C++11 and C++14 that would be nice to have.
My question is this: Would there be any way that I could build some code using a newer compiler (say MSVC2012 or 2013) to build libraries or DLLs using the newer C++11 and C++14 functionality and then link that into my project that's running the '08 compiler?
The only thing that I could think of that wouldn't work would be anywhere I had to have a C++11 or C++14 feature in a header included by my '08 compiler project. However as long as everything "new" were hidden behind my interface, shouldn't this work?
Yes but its going to get ugly.. since the ABI is not compatible you'll have to go down to the "extern "C" {}" ABIness.
That means you can't pass C++ objects at all.. like I said, painful. It also means it must be a DLL since you won't be able to link in a static lib with another ABI.
Its up to you if its worth wrapping up a DLL in a C API just to use a couple of new features or not, I would recommend just upgraded the whole project though.
I almost forgot, you probably can't link the import lib either, so you'll have to have some code that uses LoadLibrary, GetProcAddress and FreeLibrary (did I mention this is ugly/painful?).
Unfortunately, what you're trying to do is not possible with MSVC. They intentionally break binary compatibility with every major release as stated in MSDN documentation:
To enable new optimizations and debugging checks, the Visual Studio implementation of the C++ Standard Library intentionally breaks binary compatibility from one version to the next. Therefore, when the C++ Standard Library is used, object files and static libraries that are compiled by using different versions can't be mixed in one binary (EXE or DLL), and C++ Standard Library objects can't be passed between binaries that are compiled by using different versions. Such mixing emits linker errors about _MSC_VER mismatches. (_MSC_VER is the macro that contains the compiler's major version—for example, 1800 for Visual C++ in Visual Studio 2013.) This check cannot detect DLL mixing, and cannot detect mixing that involves Visual C++ 2008 or earlier.
Your options are to then only pass around POD types, or implement COM interfaces to interop between the DLLs compiled using different version of the VC compiler, neither of which is particularly palatable.
My advice would be, if you must stick with VS2008 for certain legacy applications, suck it up and deal with the feature set it supports (at least you have TR1). For newer projects, try and talk your team into using newer versions of VC.

Why is the C++ standard library bundled with the compiler instead of the os?

I am sorry if this is a naive question, but there's something I can't get my head around.
Why is the C++ standard library bundled with different compiler implementations (g++'s libstdc++ and clang's libc++) instead of coming bundled with a (UNIX-like) Operating System, just as, say the C standard library does? Why isn't it maintained alongside the C library, considering that it's a superset of it?
The basic reason is that there is no standard C++ ABI -- every compiler tends to have its own ABI that is different from and incompatible with that of other compilers. On the other hand, most OSes define a standard C ABI that they use and supply a standard C library for, and all C compilers for that OS support that ABI.
Operating systems in general do not support languages. They only support for their own system calls. In most operating systems this support is provided as part of the C library because C has the lowest level linkage. Other languages and runtimes (such as C++, python, etc) build their runtime support on top of the OS's system call support library.
The C library is also maintained separately: both glibc and Windows's msvcr* (don't know the details on Mac). The fact that is "comes with the OS" is that all (most of) the binaries are linked against it, so nothing would work without it. Granted, same could be said of the C++ standard library, but not quite so strict.
The compiler often provides extensions which library writers use to facilitate development. When a new feature is implemented, the library is adapted. Sometimes these changes are breaking. In the case of glibc/libstdc++(/libc++?), backwards compatibility is maintained inside the library (using versioned symbols). In the case of Windows' CRT, various incompatible versions appeared of both the C and C++ standard libraries, coupled to each compiler version. Also: in the case of Visual Studio, the compiler tends to break ABI between versions, so "the OS" would have to come with all versions of the libraries.
PS: granted, for Windows, it might have been "cleaner" to include newer CRT/C++lib versions in Windows Update. Other choices were made way back when, and most stuck until now.
The source code of the C++ library is bundled with the GCC sources. This makes sense, because the C++ library goes hand in hand with the C++ language. It is not an operating system component. Certain aspects of it, like memory management and I/O, do interface with OS facilities, but much of it doesn't.
On the other hand, the actual bundling of the C++ library is the job of the operating system distro (for instance some flavor of GNU/Linux).
Ultimately, it is your distribution which decides how libstdc++ is packaged. For instance, it might make sense for it to be a standalone package (which might even need to appear in several versions). This is because libstdc++ provides a shared library, and that shared library is needed as a dependency by other packages, whether or not a compiler is installed. And some packages might only work with a specific version of this library.
"Part of the OS" or "part of the compiler" don't really make sense: the question is "part of what package", and that is distro-specific, because when you build the GCC suite, your build scripts can then pick apart the temporary install tree into arbitrary packages based on your vision of how to organize a distro.
Suppose we made a "ceeplusplusy" OS distro. Then the C++ library could be considered and essential component of the OS. That is, suppose the core applications that are needed just to bring up the OS are all rewritten in C++ and all use the library: things like a system daemon, shell, "getty" and so on. Then the C++ library is needed in early boot stages. Ultimately, what is OS and what isn't?
On a Mac, you will find both libc.dylib (Standard C library) and libc++.dylib (Standard C++ library) in the /usr/lib directory. On an iOS device, you won't find them (easily), but they are both there as well. Quite clearly, they are not part of the compiler, because they are essential for practically all programs to run, and they are present even if you never installed any compilers.

MS vs Non-MS C++ compiler compatibility

Thinking of using MinGW as an alternative to VC++ on Windows, but am worried about compatibility issues. I am thinking in terms of behaviour, performance on Windows (any chance a MinGW compiled EXE might act up). Also, in terms of calling the Windows API, third-party DLLs, generatic and using compatible static libraries, and other issues encountered with mixing parts of the same application with the two compilers.
First, MinGW is not a compiler, but an environment, it is bundled with gcc.
If you think of using gcc to compile code and have it call the Windows API, it's okay as it's C; but for C++ DLLs generated by MSVC, you might have a harsh wake-up call.
The main issue is that in C++, each compiler has its own name mangling (or more generally ABI) and its own Standard library. You cannot mix two different ABI or two different Standard Libraries. End of the story.
Clang has a specific MSVC compatibility mode, allowing it to accept code that MSVC accepts and to emit code that is binary compatible with code compiled with MSVC. Indeed, it is even officially supported in Visual Studio.
Obviously, you could also simply do the cross-DLL communication in C to circumvent most issues.
EDIT: Kerrek's clarification.
It is possible to compile a large amount of C++ code developed for VC++ with the MinGW toolchain; however, the ease with which you complete this task depends significantly on how C++-standards-compliant the code is.
If the C++ code utilizes VC++ extensions, such as __uuidof, then you will need to rewrite these portions.
You won't be able to compile ATL & MFC code with MinGW because the ATL & MFC headers utilize a number of VC++ extensions and depend on VC++-specific behaviors:
try-except Statements
__uuidof
throw(...)
Calling a function without forward-declaring it.
__declspec(nothrow)
...
You won't be able to use VC++-generated LIB files, so you can't use MinGW's linker, ld, to link static libraries without recompiling the library code as a MinGW A archive.
You can link with closed-source DLLs; however, you will need to export the symbols of the DLL as a DEF file and use dlltool to make the corresponding A archive (similar to the VC++ LIB file for each DLL).
MinGW's inclusion of the w32api project basically means that code using the Windows C API will compile just fine, although some of the newer functions may not be immediately available. For example, a few months ago I was having trouble compiling code that used some of the "secure" functions (the ones with the _s suffix), but I got around this problem by exporting the symbols of the DLL as a DEF, preparing an up-to-date A archive, and writing forward declarations.
In some cases, you will need to adjust the arguments to the MinGW preprocessor, cpp, to make sure that all header files are properly included and that certain macros are predefined correctly.
What I recommend is just trying it. You will definitely encounter problems, but you can usually find a solution to each by searching on the Internet or asking someone. If for no other reason, you should try it to learn more about C++, differences between compilers, and what standards-compliant code is.

The difference between a program in C++ developed under Windows and Linux

What's the difference between a program developed in C++ under Windows and Linux?
Why can't a program developed under Windows in C++ be used under Linux?
Windows and Linux use different container formats to hold the executable code (PE vs ELF).
Windows and Linux have completely different APIs (except for trivial programs that only use the CRT and STL)
Windows and Linux have a completely different directory structure
You could write a program that can use either set of APIs (for example, using Qt), and that can handle either directory structure, but you still won't be able to run the same file on both operating systems because of the differing container formats.
This can be solved by using Wine.
Native programs are not compatible because Windows has a completely different set of API's than Linux, for one. As others have mentioned, each platform uses a different executable format as well. Also both platforms have their own set of libraries that programs will be linked against and/or share. For example, a Windows program will typically be developed in Visual Studio using windows-specific libraries such as MFC, Win32 API, etc. These libraries are not available in linux, so the program will not even compile unless care is taken to make sure cross-platform libraries (such as QT) are used.
If you are careful, however, you can use cross-platform libraries in your code and you can get the same program to compile under both platforms. For such a program you would need to carefully put any platform-specific details (file system locations, etc) in their own files. Then, you would need to setup the proper #define statements and/or makefile directives to ensure the proper files are included in the build for each platform.
Of course, if you use a "cross-platform" language such as Java or Python, and do not use any platform-specific code in your implementation, then your program can run under both environments.
Note Although the executable formats are different, some programs developed on Windows can be executed under Linux using an emulator called WINE.
In a nutshell,
Windows runs PE format executables
Linux runs ELF format executables
Furthermore, even if there were a tool to convert between PE and ELF, the program instructions necessary to interface with the operating system are completely different between Windows and Linux. Only the most restricted computation-only code (that only does calculations and doesn't interact with the operating system at all) could be ported between systems without special action. However, this is rarely done.
I believe some versions of Linux allow you to directly load device drivers designed for Windows without recompiling. However, this is an extremely special purpose application and the technique is not generally used.
Each operating system defines an API. If you code to call the Win32 API, it won't be there on Linux. If you code to the POSIX API, it won't jump right out at you in Windows.
To learn more about this, download a significant open source program (for example, Perl or Python) and see how its 'configure' script makes arrangements to compile in either place.
When a C++ program is compiled on a platform, it ultimately changes into a form that machine can understand (i.e. Machine code). Under the hood, the program uses system calls to perform privileged action. These system calls are implemented via methods or APIs. These methods differ from platform to platform. Hence on every platform, the compiled code is different. There are many cross-compilers available if you want to compile your code for a different platform.
Not to be overly pedantic, but developing a program is different than building it and executing it. In many cases, a program written on one operating system can be built and compiled to execute on another. Other programs, as others have pointed out, rely on certain functionality provided only by a particular OS or libraries resident only on that OS. As a result, it must be built and run on that OS.
C++ is itself portable. But some C++ libraries are not. If a C++ program uses some libraries, which are not portable, then this program is not portable.
For example, a C++ program uses MFC to draw the GUI stuff, because MFC is supported only in Windows, so this C++ program cannot be compiled or run on Linux directly.
There are two major reasons.
Theoretically, the same program (source code) for some languages like C, can run on both Windows and Linux. But the compilation only differs; this means you have to compile the same source code file for each platform.
But actually, each operating system has a different set of APIs. And different techniques to get job done faster... Which usually attract developers to use them. And they don't stick to standards, so they lose portability.
This was for native programs... Anyway, there are the Java and Python languages... They are truly cross-platform, but you have to sacrifice speed for sake of portability.
This is a large topic.
First, Windows and Linux aren't binary comparable. This means that even the simplest of programs will not be recognized from one machine to the other. This is why interpreted languages like PHP, Perl, Python and Java are becoming so popular, but even these don't all support the same set of features on each platform.
Library dependence / OS support: Any significantly complicated program will need to access the system is some way, and many of the features available on one system are not available on the other. There are a million examples; just look on so for the Linux equivalent of blank or Windows equivalent of blank. Moving beyond OS support applications are built mostly on top of libraries of functions and some of those are just not available on both systems.