MSVC equivalent of attribut ((warn unused result))?
je trouve __attribute__ ((warn_unused_result))
très utile comme moyen d'encourager les développeurs à ne pas ignorer les codes d'erreur retournés par les fonctions, mais j'ai besoin de cela pour travailler avec MSVC ainsi que gcc et les compilateurs compatibles gcc tels que ICC. Les compilateurs C/C++ de Microsoft Visual Studio ont-ils un mécanisme équivalent ? (J'ai essayé de surfer sur MSDN sans succès jusqu'à présent.)
5 réponses
MISE À JOUR POUR MSVC 2012 ET SUIVANTES
un grand merci à @Albert pour avoir souligné que MSVC supporte maintenant l'annotation _Check_return_
à partir de Visual Studio 2012 lors de l'utilisation de l'analyse de code statique SAL. J'ajoute cette réponse pour que je puisse inclure une macro multiplateforme qui peut être utile à d'autres:
#if defined(__GNUC__) && (__GNUC__ >= 4)
#define CHECK_RESULT __attribute__ ((warn_unused_result))
#elif defined(_MSC_VER) && (_MSC_VER >= 1700)
#define CHECK_RESULT _Check_return_
#else
#define CHECK_RESULT
#endif
noter que, contrairement à gcc et al , a) MSVC exige des annotations sur les deux déclaration et définition d'une fonction, et (b) l'annotation doit être au début de la déclaration/définition (gcc permet soit). Ainsi, l'utilisation devra typiquement être par exemple:
// foo.h
CHECK_RETURN int my_function(void); // declaration
// foo.c
CHECK_RETURN int my_function(void) // definition
{
return 42;
}
Notez également que vous aurez besoin du commutateur /analyze
(ou -analyze
) si vous compilez depuis la ligne de commande, ou l'équivalent si vous utilisez L'IDE de Visual Studio. Cela tend aussi à ralentir quelque peu la construction.
certaines éditions de VisualStudio sont fournies avec un outil d'analyse statique qui s'appelait PREFast (maintenant appelé simplement"analyse de Code pour C/C++"). Préfast utilise des annotations pour marquer le code. Une de ces annotations, doit vérifier , fait ce que vous cherchez.
autant que je sache, les compilateurs MS n'ont pas d'attribut ou de pragma équivalent - le seul avertissement de type" non utilisé " que vous pouvez obtenir est pour les variables lorsque vous avez l'optimiseur activé avec le niveau d'avertissement approprié.
je pense que l'annotation SAL que d'autres ont mentionné est le droit réponse pour MSVC, mais je devine que certaines personnes seront intéressées par plus de portabilité que de simples fournisseurs compatibles avec MSVC, GCC et GCC, alors ...
tout d'abord, GCC supporte seulement warn_unused_result
depuis 3.4. Vous mai
souhaitez vérifier les valeurs de __GNUC__
/ __GNUC_MINOR__
au lieu de
je vérifie juste si __GNUC__
est défini, bien qu'à ce point j'ai
difficulté imaginer quelqu'un utilisant une version de GCC plus ancienne que 3.4.
plusieurs compilateurs supportent L'attribut de fonction GCC-style, et peuvent ou
ne peut pas définir __GNUC__
et amis:
- Clang (vérifier avec
__has_attribute(warn_unused_result)
), et les compilateurs sur emscripten, xlc 13+, armclang, etc.), bien AFAIK il masque toujours comme au moins GCC 4.2, donc vous probablement ne pas besoin un contrôle explicite. - Intel ne définit pas toujours
__GNUC__
(voir le drapeau-no-gcc
). Je Je ne sais pas quand ils ont commencé à le supporter (leur documentation est gravement manquant), mais je sais que 16.0+ est sans danger. - TI 8.0+ prend en charge
- TI 7.3+ le supporte quand -- gcc est passé;
__TI_GNU_ATTRIBUTE_SUPPORT__
sera défini quand il sera. - Oracle Developer Studio 12.6 + le supporte en mode c++, mais pas C .
- PGI le supporte en mode C++. AFAICT il est sans-papiers, donc je ne suis pas bien sûr quand il a été ajouté (il est #1650-D), mais il est certainement présent dans 17.10+. Il est silencieusement ignoré en mode C, espérons qu'ils seront mettre en œuvre un jour.
de plus, C++17 ajoute un attribut [[nodiscard]]
. Pour les versions de
GCC / clang qui supporte [[nodiscard]]
en mode c++17 Vous pouvez aussi utiliser
[[gnu::nodiscard]]
en mode C++11 et plus, mais si vous vous cachez
derrière une macro de toute façon je ne vois pas une raison de le faire plutôt que
j'utilise juste __attribute__((__warn_unused_result__))
.
il y a un HEDLEY_WARN_UNUSED_RESULT macro in Hedley qui ressemble à:
#if defined(__cplusplus) && (__cplusplus >= 201703L)
# define HEDLEY_WARN_UNUSED_RESULT [[nodiscard]]
#elif \
HEDLEY_GNUC_HAS_ATTRIBUTE(warn_unused_result,3,4,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
HEDLEY_TI_VERSION_CHECK(8,0,0) || \
(HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \
(HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \
HEDLEY_PGI_VERSION_CHECK(17,10,0)
# define HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
#elif defined(_Check_return_) /* SAL */
# define HEDLEY_WARN_UNUSED_RESULT _Check_return_
#else
# define HEDLEY_WARN_UNUSED_RESULT
#endif
vous devriez être en mesure d'enlever les macros Hedley internes et juste copiez la logique sans trop de problèmes si vous ne voulez pas utiliser Hedley (domaine public / CC0). Si vous choisissez de le faire vous devez probablement baser votre port au large de la version dans le repo comme je le suis beaucoup moins probablement se rappeler de garder cette réponse à jour avec de nouveaux information.