59 votes

Comment déclencher un avertissement si la valeur renvoyée n'est pas prise en compte - gcc ou vérification de code statique?

Je voudrais voir tous les endroits dans mon code (C ++) qui ignorent la valeur de retour d'une fonction. Comment puis-je le faire - avec l'outil d'analyse de code statique ou gcc?

Exemple de code incorrect:

 int f(int z) {
    return z + (z*2) + z/3 + z*z + 23;
}


int main()
{
  int i = 7;
  f(i); ///// <<----- here I disregard the return value

  return 1;
}
 

Mise à jour:

  • cela devrait fonctionner même si la fonction et son utilisation sont dans des fichiers différents
  • outil de vérification statique gratuit

56voto

Eric Seppanen Points 3332

Vous voulez du CCG warn_unused_result d'attribut:

#define WARN_UNUSED __attribute__((warn_unused_result))

int WARN_UNUSED f(int z) {
    return z + (z*2) + z/3 + z*z + 23;
}

int main()
{
  int i = 7;
  f(i); ///// <<----- here i disregard the return value
  return 1;
}

En essayant de compiler ce code produit:

$ gcc test.c
test.c: In function `main':
test.c:16: warning: ignoring return value of `f', declared with
attribute warn_unused_result

Vous pouvez les voir dans l'utilisation du noyau Linux; ils ont un __must_check macro qui fait la même chose; vous ressemble besoin de GCC 3.4 ou plus pour que cela fonctionne. Alors vous trouverez que les macro utilisé dans le noyau fichiers d'en-tête:

unsigned long __must_check copy_to_user(void __user *to,
                                        const void *from, unsigned long n);

10voto

Joe Gauterin Points 9526

Vous pouvez utiliser ce modèle pratique pour le faire au moment de l'exécution.

Au lieu de renvoyer un code d'erreur (par exemple HRESULT), vous renvoyez un code_retour <HRESULT>, qui indique s'il sort de la portée sans que la valeur soit lue. Ce n'est pas un outil d'analyse statique, mais c'est néanmoins utile.

 class return_value
{
public:
  explicit return_value(T value)
    :value(value), checked(false)
  {
  }

  return_value(const return_value& other)
    :value(other.value), checked(other.checked)
  {
    other.checked = true;
  }

  return_value& operator=(const return_value& other)
  {
    if( this != &other ) 
    {
      assert(checked);
      value = other.value;
      checked = other.checked;
      other.checked = true;
    }
  }

  ~return_value(const return_value& other)
  {
    assert(checked);
  }

  T get_value()const {
    checked = true;
    return value;
  }

private:
  mutable bool checked;
  T value;
};
 

4voto

Xavier Nodet Points 2498

Tout code d'analyse statique (par exemple PC-Lint ) devrait pouvoir vous l'indiquer. Pour PC-Lint, je sais que c'est le cas.

4voto

Alon Points 4010

un analyseur statique fera le travail à votre place, mais si votre base de code est plus que triviale, préparez-vous à être submergée ;-)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X