Due to MSVC10 not allowing the use of inline ASM instructions when targeting x64 architecture, I'm looking for any ways to get around such restrictions. I have learned from googling that writing and compiling separate ASM modules then linking against them and calling them from C++ is one way, however I have no idea how I would do this. Are there any other ways, short of using the compiler intrinsics? Or how does one go about writing/compiling/linking against separate ASM modules in VS2010?
You can use a separate assembler program which will compile complete assembler source files into object files. So long as you follow the correct calling conventions you can provide prototypes for the functions for use in C++ link the C++ and ASM generated object files together.
I use yasm . It uses intel syntax, supports x64 windows and VS2010 integration. It has useful macro and include features. I must confess that I haven't had to use it since VS2008 when integration worked a bit differently, but it is supposed to work well with VS2010.
Related
I have a C++ library built in Visual Studio 2017 which uses AVX-512 intrinsics. I need to link the library to VS2008 C++ code. The library is used to extract lines from an image. All the intrinsic instructions are encapsulated within the library. VS2008 code passes in char* data, LineSpec (structure with 4 floats) and char* result, which gets filled with extracted lines.
I am unable to link the library due to error C1083: Cannot open include file: immintrin.h. I am also unable to build the library in VS2017 using VS2008 tool-set for the same reason.
The goal is to increase extraction speed with AVX-512 instructions while compiling the rest of the code with VS2008. I am new to intrinsics and mixing platforms. Do you have any suggestion on how to use the library in VS2008?
You can't
To call a function that uses ymm registers the compilers need to emit instructions to prepare those according to the ABI. But AVX-512 didn't exist in 2008, thus there's no way for VS2008 to know about the ABI or AVX-512 instructions
And then when linking you also need to know about the instruction set to know which address to fix, although this might be easier to solve with the offset stored in the object code
In short you need to update the compiler instead of using a decade-old one
I'm trying out the clang32 compiler coming with C++ builder 10.2. Builder don't yet have any good support for CMake, so a great number of 3rd party libraries are (very) hard to compile using it.
Anyone knowing if there is any binary compatibility between clang32 and Visual Studio compiler?
There are essentially three different levels of compatibility you need to worry about:
File formats for object code and debug data, which allow you to use clang to build part of your project and Visual C++ cl.exe to build a library and then link them together and debug both.
Ability to write code and structure data that conforms to a portable binary interface, so it can be called across a mix of compilers.
Binary compatibility of the C++ standard library, so that standard library objects can be shared across a mix of compilers.
I can definitely say that (2) is supported and (3) absolutely is not; you can't even share standard library objects between different patchlevels of the same compiler. For (1) I don't know. A common way to bypass the issues with (1) is to build a DLL using each compiler, so they dynamically interface but no static linking nor merging of debug data is necessary.
If your concern is about cmake though, I think your problem is not the compiler (clang is available for Linux and cmake supports it well -- you should find the make scripts are capable of configuring all the compiler options). Whether it can generate project files for C++Builder is a different story, but perhaps you should consider using a different IDE. There are many with clang support, even Microsoft's Visual Studio has some ability to use clang for the compile step, and it's getting better with each release.
Today I read on the MSDN website, that inline assembly is not supported on ARM and x64 processors. Since I'm not good at C, C++ or ASM, I couldn't test it out myself, but it sparked my interest.
I wondered if it is not possible to do this in Visual Studio, since its on the MSDN website.
Regardless of the answer to my first question, my second question remains: is it possible to compile a DLL with inline ASM, which is then called via a x64 C/C++ program to execute the inline ASM.
If so, why, and if not: why not.
Thanks in advance!
As specified by the MSDN, the VC++ compiler doesn't support inline assembly on those platforms. Of course it's not an intrinsic limitation of those platforms - it's just a feature not implemented in those versions of VC++, other compilers (e.g. gcc) support it just fine. Nothing so strange, it's not a standard feature (as in: a feature required by the C or C++ standard), it's just a common extension.
Still, even with VC++ you don't need to go as far as making a dll - you can just assemble your asm file into an object module, and link it together with the other ones (generated e.g. by the C or C++ compiler) into a single executable. This is in fact the procedure they recommend to mix C/C++ and assembly - the Microsoft assembler itself is shipped along with VC++ as always.
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.
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.