How to address C4191 warning around calls to GetProcAddress with FARPROC?

As other answers have already mentioned, this is a useful warning. Normally, this type of coercion would be a serious bug hiding in your application.

Therefore, you probably don't want to disable it globally with a compiler switch. Yet you still need to call GetProcAddress, and you like your builds to compile cleanly without warnings.

You have two good options:

  1. Suppress each individual warning using an MSVC-specific pragma. In a new line just above the maligned cast, add the following code:

    #pragma warning(suppress: 4191)
    

    This suppresses the warning for the very next line of code only, ensuring that it is not globally suppressed and you'll still get a warning if you try to do something stupid elsewhere in the code base. Of course, you'll need to add this each time you use GetProcAddress, which is kind of a pain. Worse yet, it's a non-portable, MSVC-specific extension that uglifies your code.

    So, alternatively…

  2. You can silence the warning by explicitly casting the result of GetProcAddress (a FARPROC) to void*, and then casting that void* to the specific function-pointer type. For example:

    typedef BOOL ( __stdcall *TIsWow64ProcessFunction )( HANDLE, BOOL* );
    
    TIsWow64ProcessFunction isWow64ProcessFunction =
        reinterpret_cast<TIsWow64ProcessFunction>(
           reinterpret_cast<void*>(
           ::GetProcAddress(hInstance, "IsWow64Process")));
    

    This approach will work with other compilers, is slightly less ugly, and is arguably more semantically meaningful.


You are casting a FARPROC (function pointer with no args) to a function pointer with args. Normally this is a hugely dumb thing to do that will probably result in stack corruption.

Now it turns out that GetProcAddress() doesn't really return a FARPROC and you do actually know what you're doing -- but the compiler doesn't know that and it feels obliged to warn you.

The only way you can silence it is using a #pragma or a compiler switch to turn off the warning. It is ugly and messy, but that is Windows programming for you. :-)


Basically the compiler cannot guarantee that the function is of the appropriate type, so it's unsafe for you to call the resulting pointer. However, in a VS program you don't have to link or load against the Windows .dlls explicitly, they will be loaded for you and any function in the Windows header is always available to use.