sharptooth sharptooth - 1 year ago 283
C++ Question

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

Recently I tried to use /Wall Visual C++ option to enable all warnings and found that the following code:

typedef BOOL ( WINAPI * TIsWow64ProcessFunction )( HANDLE, BOOL* );
TIsWow64ProcessFunction isWow64ProcessFunction = reinterpret_cast<TIsWow64ProcessFunction> (
::GetProcAddress( kernel32DllHandle, "IsWow64Process" ) );

spawned C4191:

warning C4191: 'reinterpret_cast' : unsafe conversion from 'FARPROC' to 'TIsWow64ProcessFunction'
Calling this function through the result pointer may cause your program to fail

If I use a C-style cast the same warning appears but now it mentions "type cast" instead of "reinterpret_cast".

The same warning is repeated for just any case I call
and convert its return value to some usable function pointer.

How do I address these warnings? Do I need to make alterations to my code?

Answer Source

You are casting a FARPROC (function pointer with no args) to a function pointer with args. Normally this is a 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.

You can silence the warning in one of two ways. First, you can cast the result of GetProcAddress() to a void*:

extern "C" {
    typedef BOOL (WINAPI * TIsWow64ProcessFunction)(HANDLE, BOOL*);

TIsWow64ProcessFunction isWow64ProcessFunction =
    (void*)::GetProcAddress( kernel32DllHandle, "IsWow64Process"));

Second, you can use #pragma or a compiler switch to turn off the warning:

extern "C" {
    typedef BOOL (WINAPI * TIsWow64ProcessFunction)(HANDLE, BOOL*);

#pragma warning(disable: 4191)
TIsWow64ProcessFunction isWow64ProcessFunction =
    ::GetProcAddress( kernel32DllHandle, "IsWow64Process"));
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download