Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.
7833 Discussions

Is there a way to avoid Visual Studio 2015 runtime when compiling with Intel Compiler?

Valued Contributor I

As the thread title says, I am compiling a DLL project using Intel Compiler and I am getting VCRUNTIME140.dll pulled in.

Of course, I am using runtime functions but I was hoping that latest Intel Compiler could fully replace it with it's own runtime.

I am asking this because I don't want my DLLs and EXEs to contain imports __telemetry_main_invoke_trigger() and __telemetry_main_return_trigger() which are in new runtime VCRUNTIME140.dll and are getting called before and after DllMain() respectively.

The options I see:

1. Recompile CRT from source and remove those entry points (whether I could redistribute that is legally questionable)
2. Patch those calls with NOPs and remove those IAT entries in a post-build step (pretty complex to do)
3. Use those few CRT functions which I need by dynamically importing from NTDLL.DLL (for that I need to find a way to disable C++ template overloads for _wcsdup() and wcscat_s() which throw error when I try to redefine them)
4. Go back to stone age and write code in MASM so that my own application can contain only the code I need and approve

Any ideas are most welcome.

Finally, and I am saying this as an end-user, not as developer -- I am seriously fed up with "modern" (read: invasive and abusive) trends in the software industry -- software testing and profiling is something that should be done on developer's own computer and their own time, not mine. How many times I start the application and which files I open are not anyone else's business but mine. Since Microsoft doesn't give us an option for privacy, Intel would do well to provide an alternative -- I am sure privacy conscious people would appreciate it.

0 Kudos
5 Replies
Black Belt

Even if you adopt mingw, you are linking msvcrt.Dll . Sharing visual studio library is a major sales point for icl.

0 Kudos
Black Belt

Why not supply your own .DLL stub library with those same named entry points, and link in the exports for your stub .dll first. You may need to also have some reference to those entry points prior to loading VCRUNTIME140.dll. Initially awkward, but at a later date, should you need those routines, it would be a matter of removing your stub library from your build.

Jim Dempsey

0 Kudos
Valued Contributor I

@Tim Prince:

I wouldn't mind linking to msvcrt.dll because it does not contain completely undocumented telemetry entry and exit points. Sadly, that seems to be impossible from Visual Studio 2015.

@Jim Dempsey:

Because I would like to avoid having even a reference to "telemetry" in things I release to other people. I don't want them getting paranoid. I don't want myself getting paranoid either, but by introducing stuff like this without any documentation whatsoever Microsoft doesn't leave me much choice in the matter.

I prefer this approach:

typedef int (__cdecl *_snprintf_s_t)(char * const _Buffer, size_t const _BufferCount, size_t const _MaxCount, char const * const _Format, ...);
typedef int (__cdecl *_vsnwprintf_s_t)(wchar_t * const _Buffer, size_t const _BufferCount, size_t const _MaxCount, wchar_t const * const _Format, va_list _ArgList);
typedef errno_t (__cdecl *wcscat_s_t)(wchar_t * _Destination, rsize_t _SizeInWords, wchar_t const * _Source);
typedef wchar_t * (__cdecl *_wcsdup_t)(wchar_t const * _String);

static _snprintf_s_t		_snprintf_s = NULL;
static _vsnwprintf_s_t		_vsnwprintf_s = NULL;
static wcscat_s_t		wcscat_s = NULL;
static _wcsdup_t		_wcsdup = NULL;

static BOOL InitFunctionPointers(void)
	HMODULE hDll = GetModuleHandleW(L"ntdll.dll");

	if (hDll == NULL) {
		return FALSE;

	wcscat_s = (wcscat_s_t)GetProcAddress(hDll, "wcscat_s");
	_wcsdup = (_wcsdup_t)GetProcAddress(hDll, "_wcsdup");
	_snprintf_s = (_snprintf_s_t)GetProcAddress(hDll, "_snprintf_s");
	_vsnwprintf_s = (_vsnwprintf_s_t)GetProcAddress(hDll, "_vsnwprintf_s");

	if ((wcscat_s == NULL) ||
	    (_wcsdup == NULL) ||
	    (_snprintf_s == NULL) ||
	    (_vsnwprintf_s == NULL)) {
		return FALSE;

	return TRUE;

However, the Visual Studio compiler complains when I do it:

1>------ Build started: Project: GLViewSDK, Configuration: Release Win32 ------
1>  GLViewSDK.cpp
1>GLViewSDK.cpp(52): error : declaration is incompatible with overloaded function "_snprintf_s" (declared at line 2045 of "C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\stdio.h")
1>    static _snprintf_s_t		_snprintf_s = NULL;
1>                        		^
1>GLViewSDK.cpp(53): error : declaration is incompatible with overloaded function "_vsnwprintf_s" (declared at line 1092 of "C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\corecrt_wstdio.h")
1>    static _vsnwprintf_s_t		_vsnwprintf_s = NULL;
1>                          		^
1>GLViewSDK.cpp(54): error : declaration is incompatible with overloaded function "wcscat_s" (declared at line 28 of "C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\corecrt_wstring.h")
1>    static wcscat_s_t		wcscat_s = NULL;
1>                     		^
1>GLViewSDK.cpp(55): error : declaration is incompatible with "__wchar_t *__cdecl _wcsdup(const __wchar_t *)" (declared at line 79 of "C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\corecrt_wstring.h")
1>    static _wcsdup_t		_wcsdup = NULL;
1>                    		^

What I don't understand is why it is using Windows 10 SDK? Shouldn't this force it to use older (i.e. 8.1) SDK?

#define _WIN32_WINNT		_WIN32_WINNT_WIN7
#define	WINVER			_WIN32_WINNT
#define	_WIN32_IE		_WIN32_IE_WIN7

#include <stdio.h>
#include <windows.h>

2. Why doing this doesn't work to disable C++ templates for those functions?


Main problem seems to be that there is no documented way to disable those C++ overloads of security enhanced functions in this header file:

C:\Program Files (x86)\Windows Kits\10\Include\10.0.10240.0\ucrt\corecrt_wstring.h

I am seriously tempted to go back to assembler at this point when trying to do one good thing (which is use security enhanced functions) brings in unwanted junk into your program.

Edit: I just found this article which explains that you cannot use msvcrt on its own anymore:

0 Kudos

I was asked to add my two cents here.

First, when you link to msvcrt.lib, you create a dependence on the current MSVC's version of the CRT, which for VS2015 would be msvcr14.dll, msvcrt.dll is the VC6 DLL - it is a "system file" in current Windows versions for the benefit of really old programs, but is otherwise of no interest.

Given that Igor is using Intel C++ for compiling, I think the solution is to add the path to an earlier MSVC's lib folder in the project property page and link to those. Since Intel C++ (currently) supports VS10-15, Igor could go back as far as VS10 for this if he wanted. He'd probably also need to add /Qvc10 to the command line options, as I think the compiler needs to know. Substitute VS12 or VS13 if desired.

I could be off-base here, since I'm definitely not a C++ expert, but I think this will work. It probably would not work if MSVC was being used to compile.

0 Kudos
Valued Contributor I

Thanks for chiming in Steve. I went on and published a rant on my website about the issue and I forgot about this thread. In the meantime it got the much needed attention on reddit where MSVC Dev Manager Steve Carroll explained what it is and how to remove in VS 2015 prior to Update 3, and in the meantime as promised Microsoft has removed those undocumented telemetry functions from CRT with VS 2015 Update 3.

I am glad that my little rant at least contributed if not outright led to Microsoft's "oops, sorry we got caught" apology on Reddit.


0 Kudos