La dépréciation du mot-clé statique… pas plus?

87

En C ++, il est possible d'utiliser le staticmot - clé dans une unité de traduction pour affecter la visibilité d'un symbole (déclaration de variable ou de fonction).

Dans n3092, ceci était obsolète:

Annexe D.2 [depr.static]
L'utilisation du mot clé static est déconseillée lors de la déclaration d'objets dans la portée de l'espace de noms (voir 3.3.6).

Dans n3225, cela a été supprimé.

Le seul article que j'ai pu trouver est un peu informel.

Cela souligne cependant que pour la compatibilité avec C (et la possibilité de compiler des programmes C en C ++), la dépréciation est ennuyeuse. Cependant, compiler un programme C directement en C ++ peut déjà être une expérience frustrante, donc je ne sais pas si cela mérite d'être pris en considération.

Est-ce que quelqu'un sait pourquoi il a été changé?

Matthieu M.
la source
3
Vous déclarez des objets à la portée de l'espace de noms en C?
Etienne de Martel
heh, thx, a trouvé où se le procurer. J'ai essayé de supprimer le commentaire mais tu m'as battu là-bas.
Edward Strange
Question posée sur stackoverflow.com/questions/4725204/…
Fred Nurk
1
Cela donne également au Comité C ++ la possibilité d'annuler quelque chose dans la prochaine version du Standard :-)
James McNellis

Réponses:

74

Dans C ++ Standard Core Language Defect Reports and Accepted Issues, Revision 94 under 1012. Undeprecating static `ils notent:

Bien que 7.3.1.1 [namespace.unnamed] déclare que l'utilisation du mot-clé static pour déclarer des variables dans la portée de l'espace de noms est obsolète car l'espace de noms sans nom fournit une alternative supérieure, il est peu probable que la fonctionnalité soit supprimée à tout moment dans un avenir prévisible .

En gros, dire que la dépréciation de staticn'a pas vraiment de sens. Il ne sera jamais supprimé de C ++, et il est toujours utile car vous n'avez pas besoin du code standard dont vous avez besoin avec des espaces de noms sans nom, si vous souhaitez simplement déclarer une fonction ou un objet avec un lien interne.

Johannes Schaub - litb
la source
2
Eh bien, il semble que la dépréciation encouragerait les gens à utiliser à la place des espaces de noms sans nom, ce qui serait une bonne chose.
sbi
1
@unaperson: Si pour aucune autre raison, alors parce que les espaces de noms sans nom fournissent le même mécanisme pour rendre les variables, les constantes, les fonctions et les types internes à leur TU. static class ... , OTOH, ne fonctionnera pas.
sbi
2
@nbt: Parce que vous ne pouvez pas utiliser de symboles statiques comme arguments de modèle et parce que de nombreux débutants trouveraient la statique plus facile à utiliser et ne seraient donc pas tentés d'essayer <functional> et <algorithm> et al. Juste une petite pensée.
Sebastian Mach
2
"parce que vous n'avez pas besoin du code standard dont vous avez besoin avec des espaces de noms sans nom"? Quel "code passe-partout"? Quelque chose au-delà de " namespace {" et " }"?
Towi
1
@ErikAronesty Si vous avez une "classe locale" dans un autre fichier avec le même nom, vous commettrez une violation ODR.
LF
32

J'essaierai de répondre à votre question, bien que ce soit une vieille question, et elle n'a pas l'air très importante (ce n'est vraiment pas très important en soi ), et elle a déjà reçu d'assez bonnes réponses. La raison pour laquelle je veux y répondre est que cela se rapporte à des problèmes fondamentaux de l'évolution standard et de la conception du langage lorsque le langage est basé sur un langage existant: quand les fonctionnalités du langage doivent-elles être obsolètes, supprimées ou modifiées de manière incompatible?

En C ++, il est possible d'utiliser le mot-clé static dans une unité de traduction pour affecter la visibilité d'un symbole (déclaration de variable ou de fonction).

Le lien en fait.

Dans n3092, ceci était obsolète:

La dépréciation indique:

  • L' intention de supprimer certaines fonctionnalités à l'avenir; cela ne signifie pas que les fonctionnalités obsolètes seront supprimées dans la prochaine révision standard, ou qu'elles devront être supprimées "bientôt", ou pas du tout. Et les fonctionnalités non obsolètes peuvent être supprimées dans la prochaine révision standard.
  • Une tentative formelle de décourager son utilisation .

Ce dernier point est important. Bien qu'il n'y ait jamais de promesse formelle que votre programme ne sera pas rompu, parfois silencieusement, par la prochaine norme, le comité devrait essayer d'éviter de briser un code «raisonnable». La dépréciation devrait indiquer aux programmeurs qu'il est déraisonnable de dépendre de certaines fonctionnalités .

Cela souligne cependant que pour la compatibilité avec C (et la possibilité de compiler des programmes C en C ++), la dépréciation est ennuyeuse. Cependant, compiler un programme C directement en C ++ peut déjà être une expérience frustrante, donc je ne sais pas si cela mérite d'être pris en considération.

Il est très important de conserver un sous-ensemble commun C / C ++, en particulier pour les fichiers d'en-tête. Bien entendu, staticles déclarations globales sont des déclarations de symbole avec lien interne et cela n'est pas très utile dans un fichier d'en-tête.

Mais le problème n'est pas seulement la compatibilité avec C, c'est la compatibilité avec le C ++ existant: il existe des tonnes de programmes C ++ valides existants qui utilisent staticdes déclarations globales. Ce code n'est pas seulement formellement légal, il est sain, car il utilise une fonctionnalité de langage bien définie de la manière dont il est destiné à être utilisé .

Ce n'est pas parce qu'il existe maintenant une «meilleure façon» (selon certains) de faire quelque chose que les programmes écrits à l'ancienne sont «mauvais» ou «déraisonnables». La possibilité d'utiliser le staticmot - clé sur les déclarations d'objets et de fonctions à portée globale est bien comprise dans les communautés C et C ++, et le plus souvent utilisée correctement.

Dans la même veine, je ne vais pas changer les moulages de style C doubleen static_cast<double>simplement parce que "les moulages de style C sont mauvais", car cela static_cast<double>n'ajoute aucune information et aucune sécurité.

L'idée que chaque fois qu'une nouvelle façon de faire quelque chose est inventée, tous les programmeurs se précipiteraient pour réécrire leur code de travail bien défini existant est tout simplement folle. Si vous voulez supprimer toute la laideur et les problèmes hérités du C, vous ne changez pas le C ++, vous inventez un nouveau langage de programmation. La suppression de la moitié d'une utilisation de staticrend à peine C ++ moins C-laid.

Les changements de code nécessitent une justification, et «vieux est mauvais» ne justifie jamais les changements de code.

Les changements de langue brisés nécessitent une justification très forte. Rendre le langage très légèrement plus simple ne justifie jamais un changement radical.

Les raisons données pour lesquelles staticest mauvais sont simplement remarquablement faibles, et il n'est même pas clair pourquoi les objets et les déclarations de fonctions ne sont pas déconseillés ensemble - leur donner un traitement différent ne rend guère le C ++ plus simple ou plus orthogonal.

Alors, vraiment, c'est une triste histoire. Pas à cause des conséquences pratiques qu'il a eues: il n'a eu exactement aucune conséquence pratique. Mais parce que cela montre clairement un manque de bon sens de la part du comité ISO.

curieux
la source
5
Comme vous le faites remarquer vous-même, le but de la déprécier est de décourager son utilisation. Pourtant, vous ne prétendez pas que décourager son utilisation est une erreur. J'espère certainement que personne n'encourage les gens à utiliser des déclarations statiques à portée d'espace de noms sur des espaces de noms anonymes. Pas à moins qu'ils n'aient spécifiquement besoin de croiser la compilation C.
Nicol Bolas
2
Je ne me soucie pas beaucoup des personnes utilisant une portée globale staticou des espaces de noms anonymes, je n'encourage ni ne décourage non plus. Ce que je veux dire, c'est que si vous voulez vraiment décourager les gens d'utiliser des espaces de noms anonymes, vous devez leur donner de bons arguments. En pratique, je crois que dans la plupart des implémentations, les entités déclarées dans un espace de noms sans nom sont des symboles exportés avec un nom aléatoire, augmentant ainsi la table d'exportation. Les entités déclarées comme staticOTOH ne sont en aucun cas exportées. Ainsi, de nombreuses personnes choisissent, sur la base de cette observation, d'utiliser static.
curiousguy
2
« Comme vous le faites remarquer vous-même, le but de la déprécier est de décourager son utilisation. » L'intérêt de décourager son utilisation est qu'elle pourrait disparaître un jour. Mon point est que la portée de l'espace de noms staticne disparaîtra jamais, il est donc erroné de la désapprouver. " Pourtant, vous ne faites aucun argument selon lequel décourager son utilisation est une erreur. " Je n'ai vu aucun argument convaincant qui montre que l'utilisation de la portée de l'espace de noms staticest "incorrecte". Le déprécier juste pour décourager son utilisation est une erreur, parce que personne ne croit réellement qu'il va disparaître, et parce que cela ne convainc pas les gens que son utilisation est "mauvaise".
curiousguy
5
La langue entière "disparaîtra un jour". Déprécions C ++.
Courses de légèreté en orbite le
2
"Dans le même ordre d'idées, je ne vais pas changer les moulages de style C pour doubler en static_cast <double> simplement parce que" les moulages de style C sont mauvais ", car static_cast <double> n'ajoute aucune information et aucune sécurité." Mon éternel combat avec de nombreux ingénieurs logiciels qui ne cessent de se plaindre de mon utilisation libertine du style C passe d'un primitif à l'autre.
Makogan
14

Déconseillée ou non, la suppression de cette fonctionnalité de langue briserait les codes existants et ennuyait les gens.

Tout le problème de la dépréciation statique était juste un vœu pieux comme "les espaces de noms anonymes sont meilleurs que statiques" et "les références sont de meilleurs pointeurs". Lol.

Maxim Egorushkin
la source
1
"Les références sont de meilleurs indicateurs"? Non, les pointeurs intelligents sont des pointeurs plus intelligents. Vous ne pouvez pas utiliser de références pour la mémoire allouée à partir du tas, err, magasin libre.
Dan Breslau
3
Désolé, j'ai oublié de terminer avec un smiley ironique.
Maxim Egorushkin
2
@Dan: C'est exactement ce que dit cette réponse: des "vœux pieux" le long d'une ligne de pensée erronée similaire. Les espaces de noms sans nom sont une fonctionnalité importante, tout comme global-scope-static, bien que pour des raisons légèrement différentes, et même s'ils ont un certain chevauchement dans l'applicabilité.
Fred Nurk
@Fred, @Maxim: Désolé si j'ai mal compris ou si ma mémoire est défectueuse. Mais je ne classe pas «les références sont de meilleurs pointeurs» comme étant l'équivalent de «les espaces de noms anonymes sont meilleurs que statiques» comme un cas de vœux pieux. Je suis bien conscient de la tentative de faire adhérer ce dernier, mais je ne me souviens pas que quiconque ait fait une proposition sérieuse de remplacer les pointeurs par des références. Encore une fois, c'est peut-être ma propre conscience qui manque.
Dan Breslau
1
@DanBreslau: Le simple char* foo = new char; char& ref = *foo;fait qu'un pointeur vous soit initialement donné ne dit absolument rien sur votre capacité à utiliser des références.
Courses de légèreté en orbite le