Comment adresser l’avertissement C4191 autour des appels à GetProcAddress avec FARPROC?

Récemment, j’ai essayé d’utiliser l’ option / Wall Visual C ++ pour activer tous les avertissements et trouvé le code suivant:

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

C4191 engendré:

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

Si j’utilise un casting de style C, le même avertissement apparaît, mais il mentionne désormais “cast de type” au lieu de “réinterpréter_cast”.

Le même avertissement est répété pour n’importe quel cas. J’appelle GetProcAddress() et convertis sa valeur de retour en un pointeur de fonction utilisable.

Comment puis-je répondre à ces avertissements? Dois-je modifier mon code?

Vous convertissez un FARPROC (pointeur de fonction sans argument) en un pointeur de fonction avec argument. Normalement, c’est une chose extrêmement stupide à faire qui entraînera probablement une corruption de stack.

Maintenant, il s’avère que GetProcAddress () ne renvoie pas vraiment un FARPROC et vous savez réellement ce que vous faites – mais le compilateur ne le sait pas et se sent obligé de vous prévenir.

La seule façon de le désactiver consiste à utiliser un # pragma ou un commutateur de compilateur pour désactiver l’avertissement. C’est moche et désordonné, mais c’est la programmation Windows pour vous. 🙂

Comme d’autres réponses l’ont déjà mentionné, il s’agit d’un avertissement utile. Normalement , ce type de coercition constituerait un grave bug caché dans votre application .

Par conséquent, vous ne voulez probablement pas le désactiver globalement avec un commutateur de compilateur. Cependant, vous devez toujours appeler GetProcAddress , et vous aimez que vos compilations se comstacknt proprement sans avertissements.

Vous avez deux bonnes options:

  1. Supprimer chaque avertissement individuel en utilisant un pragma spécifique à MSVC. Dans une nouvelle ligne juste au-dessus de la dissortingbution malignée, ajoutez le code suivant:

     #pragma warning(suppress: 4191) 

    Cela supprime l’avertissement pour la toute prochaine ligne de code uniquement , en veillant à ce qu’il ne soit pas globalement supprimé et vous recevrez toujours un avertissement si vous essayez de faire quelque chose de stupide ailleurs dans la base de code. Bien sûr, vous devrez append cela chaque fois que vous utiliserez GetProcAddress , ce qui est GetProcAddress . Pire encore, il s’agit d’une extension non portable, spécifique à MSVC, qui gêne votre code.

    Alors, alternativement…

  2. Vous pouvez désactiver l’avertissement en GetProcAddress explicitement le résultat de GetProcAddress (un FARPROC ) sur void* , puis en transmettant ce void* au type de pointeur de fonction spécifique. Par exemple:

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

    Cette approche fonctionnera avec les autres compilateurs, est légèrement moins laide et sans doute plus significative d’un sharepoint vue sémantique.

Fondamentalement, le compilateur ne peut pas garantir que la fonction est du type approprié, il est donc dangereux pour vous d’appeler le pointeur résultant. Cependant, dans un programme VS, vous n’avez pas à lier ou à charger explicitement les fichiers .dll de Windows, ils seront chargés pour vous et toute fonction de l’en-tête Windows sera toujours disponible.