We recently had a new requirement to use the phonon component of Qt, which on windows requires Visual Studio.
I installed VS2008 and ran a compile. There are a stack of problems due to make not working anything like nmake.
Since I need to maintain cross-platform I want to test which compiler is being used so that I can make changes as required.
An example is that the PRETTY_FUNCTION is a g++ macro with FUNCDNAME being the VC equivalent. How do I test which compiler I am using to determine which macro to call?
Use the _MSC_VER macro. If it is defined, you're using Visual Studio:
#ifdef _MSC_VER
... MSVC code ...
#else
... other compiler ...
#endif
Related
MSVC 2019 has added a new _udiv128() intrinsic (documentation)
that I would like to use in my C++ code. However that intrinsic is currently not available in both clang-cl 9.0.0 and the Intel C++ compiler 2019 even though these compilers set _MSC_VER=1920 just like MSVC 2019.
Because of this issue the code below does not compile using both clang-cl and icl:
#include <immintrin.h>
#if _MSC_VER >= 1920
uint64_t res = _udiv128(a, b, c, &d);
#endif
Is there a way to detect MSVC using the preprocessor without detecting clang-cl, icl, ... I would like to avoid checking for _MSC_VER and then excluding all other C/C++ Windows compilers.
Ideally I would like to detect MSVC using a Microsoft specific macro that is only defined for MSVC but not for clang-cl, icl...
I can't speak for the Intel compiler.
Clang-cl defines _MSC_VER because it's trying to be a drop-in replacement for the MSVC compiler and to use the MS libraries that come with the compiler (e.g., the C RTL and the C++ Standard Library). Those library implementations depend on _MSC_VER, so clang-cl doesn't really have an option.
Options:
Seva's proposal from the comments will work for you. I understand is not your preferred solution, but it is an option. You could test it in one place so that you only have to update one place when the situation improves.
Try using the -fms-compatibility-version clang-cl flag to choose an older version. (If you don't provide this flag, clang-cl tries to discover you MSVC installation and then matches the compatibility flag to that installations libraries, which is probably why you're seeing exactly 1920.) This will prevent your #if _MSC_VER >= 1920 from triggering, but it could have side-effects if there are parts of the system libraries that require 1920-or-better.
Wait for clang-cl to implement _udiv128(). Better yet, propose a patch to get it done sooner.
Background
I'm writing a C++ app using VS2015 on WIN 7. This app will run on all windows OS greater than equal to XP.
Through out my code, I use lots of WINAPI calls.
I wish to prevent, at compile time, the usage of API that are not defined in win XP.
Motivation
At some point, I used function RegDeleteKeyEx function without noticing that this API is NOT available in win XP
Solution
So, I follow this post: Modifying WINVER and _WIN32_WINNT and declared this:
#include <winsdkver.h>
#define _WIN32_WINNT 0x0501
#define WINVER 0x0501
in file targetver.h
I was hoping that after this fix, when I compile my project that contains usage of RegDeleteKeyEx function, I will get compilation error.
But I didn't.
QA
I tried looking for other, new WINAPI in vista, and just added a call to GetTickCount64 function. when compiling, I got this:
error C3861: 'GetTickCount64': identifier not found
which confirmed my solution.
Question
I've noticed that for RegDeleteKeyEx function, the Minimum supported client is Windows Vista, Windows XP Professional x64 Edition
However, my app will run in XP 32 as well.
How may I enforce compilation error in such use case?
Unfortunately, as I can see in "winreg.h", there is no conditional compilation of RegDeleteKeyEx (other than RegDeleteKey). So there is no (easy) way to trigger compilation error in this case.
The only option (for the regular statical DLL loading) would be to create your own wrapper over winreg.h (or windows.h) which would handle the version check (and e.g. #undef RegDeleteKeyEx in the corresponding cases).
Sometimes this kind of stuff is also solved using dynamic DLL loading (LoadLibrary / GetProcAdress) where you can check the presence of the particular function on the current version of Windows, where the application runs (so you could for example create a RegDeleteKey wrapper which would call RegDeleteKeyEx on the windows versions which support it and RegDeleteKey if run under versions which don't). The check of the feature presence is then done at runtime, so the program can run on any version of system and still use the newest features on the versions which support them (and doesn't have DLL "unresolved import" loading issues on the lower versions which do not support the feature).
Are there any C++ compile time macros which exists to detect which Windows OS the code is being compiled on. I basically want to support certain functions only on Win7. So I am interested in doing something like this
#if <os_macro> = WIN7
// This function would do something valid only on Win7 builds.
bool myfunction {
// do something here
}
#else
// This function would typically return false, since its not supported on OS below win7
bool myfunction {
return false;
}
#endif
Is there any other better way to do this?
The OS that it's getting compiled on is not all that important; what matters more is the OS that the code is running on, which you obviously cannot detect at compile time. But if you want your code to run on older versions of Windows, you can set WINVER and _WIN32_WINNT to certain values, which will cause newer functions not to be available etc. (just search the Windows header files for where those macros get tested to get an idea).
To test for functionality at runtime, use GetProcAddress (and possibly also LoadLibrary, if it's in a newer DLL) to test if the function is available. If it is, call it, if not, don't.
See also the predefined macros used by the Visual Studio compiler if you want to detect the compiler version etc.
There are a set of standard windows header macros to tell you the exact version of the OS
There are certain things that do require knowing which OS version at compile time.
For example import "winhttp.dll" will compile under Windows 7, but cause compile time error (C1083) under Windows 10.
But if you switch to import "winhttpcom.dll". It would compile under Windows 10 but fail under Windows 7.
So an OS macro is needed here to import appropriate dll.
At least with MS VC++, WIN32, _WIN32, and _WIN32_WINNT, for starters. Unless you need to control it at compile time, you might consider using something like GetVersionEx to detect at run-time, so the same build runs on older versions, but takes advantage of new features when they're available.
My response is 10 yrs late but posting the answer for upcoming yrs.
For detecting the version c/c++ compiler version can be used. Suitable macro is mentioned below:
_MSC_VER
_MSC_FULL_VER
Reference: MS macros
My two cents for people that want to compile / include differently between CONSOLE and WIN32 App under visual Studio (2017) in my case.
You you use wizard to create a Console App, You will have:
WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
under:
If You use wizard for win32 GUI App:
WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
so NO _CONSOLE.
so You can write:
#ifdef _CONSOLE
// for Console
#else
// for GUI
#endif // _CONSOLE
int main()
{
#ifdef _CONSOLE
// for Console
#else
// for GUI
#endif // _CONSOLE
return 0;
}
I like the Visual Studio IDE. I'm used to it and find it is the best IDE I've ever tried. We also find increasing use of C#/.NET here.
However, after the underwhelming announcement regarding C++11 features in VS11 I'm looking into replacing the compiler.
It seems that the Intel compiler fully integrates with VS but that doesn't mean it will compile our Windows code. I don't know how I'd fare with a try of g++ or clang
Can VS actually be productively used with a different C++ compiler to compile Windows code, that is legacy code using all kinds of Win32 / MFC / COM stuff?
Depends on how much use you made of the Microsoft-proprietary extensions. Things like #pragma once tend to be supported by all the major compilers, but the weirder COM things (e.g., #import and anything C++/CLI) probably won't be. No idea if MFC will build under the new compiler, but you'll probably have to link it statically or ship your own DLL; G++ definitely uses a different mangling scheme than MSVC.
I'm not sure how easy it is to replace cl.exe and keep your vcproj files intact (though some compilers actually do it), but there are always Makefile projects.
I have never actually worked with the Intel C++ compiler, but I see no reason why it wouldn't compile the code that VC++ does. Here is official Intel documentation.
I use Visual Studio 2008 with a Makefile project to cross-compile; no reason you couldn't do the same with a different Windows compiler.
I fail to compile a C++ project for mobile device with Windows Mobile (Windows CE-based) operating system and Visual C++ compiler from Visual Studio fails with:
Error 1 fatal error C1083: Cannot open include file: 'io.h'
EDIT
I am trying to compile the SQLite amalgamation, the shell.c file includes the call to this io.h but the io.h is missing from the files.
I googled and I couldn't locate how can I get this .h file.
Can someone point me in the right direction?
The io.h file is not available in SDKs for Windows CE-based systems like Windows Mobile.
In fact, io.h header has never been a part of ISO C nor C++ standards. It defines features that belongs POSIX compatibility layer on Windows NT, but not Windows CE.
Due to lack of POSIX features on Windows CE, I developed a small utility library WCELIBCEX. It does include io.h but a very minimal version and which is likely insufficient for SQLite. However, as ctacke mentioned, you should use SQLite port for Windows CE because original version of SQLite is not compilable for this platform.
p.s. Note, Your question does not specify explicitly that you're building for Windows Mobile. If one doesn't spot the .NET Compact Framework mentioned in tags, then the whole question is ambiguous.
It looks like io.h is part of standard VS, but proobably not part of WINCE edition (if there is one). From your dir /s it looks like you don't have it.
I looked at shell.c and it does not include io.h that for wince:
#if defined(_WIN32) || defined(WIN32)
# include <io.h>
#define isatty(h) _isatty(h)
#define access(f,m) _access((f),(m))
#else
/* Make sure isatty() has a prototype.
*/
extern int isatty();
#endif
#if defined(_WIN32_WCE)
/* Windows CE (arm-wince-mingw32ce-gcc) does not provide isatty()
* thus we always assume that we have a console. That can be
* overridden with the -batch command line option.
*/
#define isatty(x) 1
#endif
You are probably compiling with the wrong macros defined.
Have you considered looking at the project files from the SQLite for Windows CE site to see how they got it to compile for CE? I've never seen native code files designed for the desktop ever "just compile" for Windows CE without having to do some preprocessor work and it's likely they've got the answers to what you need in those projects.
Found something that looks like your problem here. Apparently, althought io.h is a standard Microsoft header, there is no port of it to mobile plataforms.
You are probably using some library that was not designed for use with mobile devices, and that library must be trying to use the non-mobile API.
If you see this error while trying to install a Python library, follow https://stackoverflow.com/a/16588726/284795
Basically, remove visual studio 2010, then some registry keys manually then reinstall. Worked for me.