9
votes

Comment une fonction [[Noreturn]] peut-elle avoir un type de retour?

J'ai rencontré ce "beau" exemple de code "très lisible" et "élégant", mais j'ai des problèmes de la compréhension: xxx

Voici ce que je comprends (veuillez me corriger si Je me trompe):

  • f () est une fonction de membre de s
  • virtuel - peut être remplacé par des classes dérivées
  • inline - compilateur devrait tenter de générer le code pour un appel à f plutôt que de l'appeler normalement
  • const - la fonction n'est pas en mesure de modifier l'un des membres s s
  • noexcept - La fonction ne jettera jamais (ne peut pas lancer ou non autorisé à lancer)
  • Paramètre: A const pointeur sur un const Unsigned long int
  • auto .... -> vide - type de retour vide
  • [[NORESTURN]] - il n'a jamais retour s

    Voici mes principales préoccupations:

    • Si une fonction est déclarée comme [[Noreturn]] , il jamais retourne à son appelant; Alors, comment peut-il avoir un type de retour void ? Quel est le point d'un type de retour dans cette fonction quand même?
    • Ce code compilait-il avec int au lieu de void par exemple?
    • Quelle serait une utilisation pratique pour une fonction comme ça? Jeter une exception?
    • Où le flux du code a-t-il opté après la fin de cette fonction exécutant (après } )?

      Je n'ai pas pu obtenir ce code à exécuter sur VS2013 Aperçu, je suppose donc que ces fonctionnalités n'étaient pas encore implémentées.

      Je suis très curieux de cela, alors je l'apprécierai si quelqu'un peut expliquer! Acclamations


9 commentaires

@TemplaTerex En réalité, ce n'est pas un dupliqué car j'ai posé 4 questions à la fin qui nécessitent plus d'informations que ce qui a été répondu dans ce poste


Eh bien, ces autres questions sont insuffisamment prises en charge avec le code, c'est-à-dire un SSCCE et quoi-vous-t-il?


@TemplaTerex Je ne peux rien essayer car mon compilateur ne comprend même pas ce que [[Noreturn]] signifie. J'ai besoin d'aide, c'est pourquoi je demande.


Il y a beaucoup de compilateurs en ligne qui l'appuient, vous devriez vraiment mettre en œuvre plus d'efforts pour réduire votre question, car d'autres pour pouvoir vous aider


@Templatérex Comment puis-je le réduire? J'ai posé 4 questions spécifiques, j'ai besoin de répondre pour eux! Ceci est un site Web Q +. me faisant référence à un poste qui ne répond pas non plus de mes 4 questions n'est pas vraiment utile pour moi ou quelqu'un d'autre


Alors que la première des quatre questions est répondue dans la question indiquée comme duplicata, les trois autres ne le sont pas et ce sont des questions valables. Alors peut-être peut-être supprimer cette première question. Vous avez mon vote pour la réouverture. @TemplaTerex Il n'y a rien à rétrécir dans la troisième et quatrième question, et si vous lisez la seconde comme "la norme permet de" la norme ", il n'y a pas de rétrécissement pour la seconde non plus.


Merci @arnemertz, je comprends déjà tout - la réponse de Dietmarkühl a fait tout ce qui est clair


@Arnemetz La 3ème question a également été répondue dans le Q & A lié. On ne peut s'attendre à poser une question avec un titre qui est clairement en double et prétend que ce n'est pas un duplicata, car 2 sous-requêtes sur 4 sont nouvelles. Affiches (et clairement que l'OP est un utilisateur expérimenté de manière à ce que vous puissiez faire des efforts supplémentaires pour faire des recherches préalables. Si seulement les 2 sous-questionnaires uniques avaient été posées et que les questions et réponses liées ont été mentionnées à l'avance - et pourquoi cela ne fournit pas assez d'informations - alors je n'aurais pas voté à proximité.


Op, je vous suggère de simplifier l'exemple de ne pas contenir d'éléments immatériels pour votre question (comme struct s ; qui se soucie de cela, non?).


4 Réponses :


19
votes

Le [[Noreturn]] est un attribut qui a la sémantique qu'elle a. Cela ne change pas, cependant, comment la fonction est déclarée: toutes les fonctions normales en C ++ (c'est-à-dire toutes les fonctions, à l'exception des constructeurs, destructeurs et des opérateurs de conversion) ont un type de retour déclaré. L'ajout d'un attribut ne change pas cette règle.

Le but de l'attribut [[noreturn]] est probablement d'indiquer que la fonction ne revient jamais de manière normale. Étant donné que la fonction est également déclarée noexcept signifie essentiellement que la fonction correspondante ne peut également être lancée d'une exception. Un exemple de fonction avec un comportement similaire est Quitter () qui termine le programme. Je pouvais imaginer que les fonctions mettant en œuvre une sorte de boucle d'application pourraient également être admissibles. Dans tous les cas, le [[Noreturn]] indique au système que la fonction correspondante ne reviendra jamais normalement, c'est-à-dire la chute de la fonction ("après}") entraînera probablement un comportement non défini.


0 commentaires

6
votes

Si une fonction est déclarée [[Noreturn]], elle ne revient jamais à son appelant; Alors, comment peut-il avoir un vidage de type retour? Quel est le point d'un type de retour dans cette fonction quand même?

de Ce Q & A Vous pouvez voir que Nor ouTurn est Un moyen de dire au compilateur qu'une fonction ne renvoie pas. Normalement, cela signifie qu'il a une boucle infinie (souvent observée dans des serveurs censés fonctionner indéfiniment) ou cela appelle indéfiniment) ou appelle sortie () , terminer () et similaire. l'application sans retourner à la main.
[[NORÉTURN]] est facultatif, c'est-à-dire que vous ne avez-vous pour spécifier. C'est un attribut, c'est-à-dire la syntaxe de base de la définition / la déclaration de la fonction restent intacte, de sorte que la fonction a doit avoir un type de retour comme toute autre fonction.

Ce code compilait-il avec Int au lieu de void par exemple?

Oui, ce serait, bien que le compilateur puisse vous avertir que cela n'a pas de sens que quelque chose est retourné d'une fonction qui ne revient jamais.

Quelle serait une utilisation pratique pour une fonction comme celle-là? Jeter une exception?

La première chose qui vous vient à l'esprit est une boucle sans fin, par ex. Manipulation des demandes entrantes sur un serveur. Lancer une exception est correct pour [[Noreturn]] fonctionne également, mais ce n'est pas vraiment une option ici, car il dit explicitement noexcept . Lancerait déclencher un appel à std :: terminer () , conduisant à la résiliation du programme lui-même mais préside à une quantité de mise en oeuvre définie de la pile déroulant, ce qui signifie en fait [[NORETURN]] serait toujours applicable.

Où est-ce que le flux du code est passé après la fin de cette fonction exécutant (après})?

La fonction n'atteint jamais sa fermeture } . Il fonctionne sans fin (jusqu'à ce que quelqu'un tire la fiche), ou il sort de manière anormale, c'est-à-dire par résiliation du programme. En d'autres termes, si la fonction n'exécute plus, elle n'a pas vraiment fini, mais a abandonné l'exécution , et il n'y a pas de programme et aucun flux de contrôle pour aller à.


2 commentaires

Si je ne me trompe pas, une exception échappatoire noexcept fonctionne en appelant std :: Terminez et la pile peut ou non déroulé (mise en oeuvre définie). Donc, il peut-être entraîner des destructeurs appelés.


@Jrok Vous avez raison, c'était vieux C ++ 03 Info que j'avais - allez résoudre ce problème.



2
votes

Les autres réponses sont excellentes, mais je vais présenter une réponse alternative pour

Si une fonction est déclarée sous forme [[Noreturn]] code>, il ne revient jamais à son appelant; Alors, comment peut-il avoir un vidage de type retour? Quel est le point d'un type de retour dans cette fonction quand même? P> blockQuote>

Une des raisons pour lesquelles vous pourriez avoir besoin d'un type de retour (et un type de retour non vides à cela) est si la fonction remplace une méthode Super Classes. P>

struct Parent {
   virtual int f()=0;
}

struct Child {
    [[noreturn]] override int f() noexcept { ... }
};


0 commentaires

0
votes

Si une fonction est déclarée [[Noreturn]], elle ne revient jamais à son appelant; Alors, comment peut-il avoir un vidage de type retour? Quel est le point d'un type de retour dans cette fonction quand même?

J'ai trouvé un exemple pratique d'un non-vide [[Noreturn]] fonction. C'est dans un cas, lorsqu'il est utilisé dans ?: Opérateur pour fournir un résultat correct de type ?: opérateur: xxx < P> Remarque: on pourrait avoir un sentiment que [[noréturn]] fonctionne dans ?: Opérateur pourrait être ignoré pour le calcul de ?: résultat taper. Mais il n'est pas possible car [[NORETEURCH]] n'est pas une partie du type de résultat d'une expression ( échoue ("") a le type de résultat T et non [[NORETURN]] T ).

Quelle serait une utilisation pratique pour une fonction comme celle-là? Jeter une exception?

Voir l'exemple de cette fonction échouer ci-dessus.


0 commentaires