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.)

22
demandé sur Paul R 2010-11-19 18:12:12

5 réponses

c'est _Check_return_ . Voir ici pour des exemples d'annotations similaires et ici pour le comportement de la fonction. Il est supporté depuis MSVC 2012.

exemple:

_Check_return_
int my_return_must_be_checked() {
    return 42;
}
13
répondu Albert 2014-03-31 07:12:23

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.

8
répondu Paul R 2014-03-31 10:33:45

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.

5
répondu John Dibling 2017-05-23 12:01:51

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é.

3
répondu Timo Geusch 2010-11-19 15:21:02

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.

1
répondu nemequ 2018-03-24 18:33:45