C est un peu, pas exactement, un sous-ensemble de C ++. Nous pouvons donc utiliser la plupart des fonctions / en-têtes C en C ++ en changeant un peu le nom ( stdio.h
to cstdio
, stdlib.h
to cstdlib
).
Ma question est en fait un peu sémantique. En code C ++ (en utilisant la dernière version du compilateur GCC), je peux appeler printf("Hello world!");
et std::printf("Hello world!");
et cela fonctionne exactement de la même manière. Et dans la référence que j'utilise, il apparaît également sous la forme std::printf("Hello world!");
.
Ma question est la suivante: est-il préférable d'utiliser std::printf();
en C ++? Y a-t-il une différence?
c++
language-lawyer
std
DeiDei
la source
la source
C
symboles de bibliothèque dans l'espace de noms global soit illégal, je préfère utiliser lesstd::
versions qualifiées. (De plus, j'aurais aimé qu'ils l'aient rendu illégal).Réponses:
De la norme C ++ 11 (c'est moi qui souligne):
L'utilisation des en-têtes «name.h» est obsolète, ils ont été identifiés comme candidats à la suppression des futures révisions.
Donc, je suggérerais d'inclure les en-têtes «cname» et d'utiliser les déclarations et définitions de l'
std
espace de noms.Si vous devez utiliser les en-têtes «name.h» pour certaines raisons (c'est obsolète, voir ci-dessus), je vous suggère d'utiliser les déclarations et définitions de l'espace de noms global.
En d'autres termes: préférez
plus de
la source
<cmeow>
fournit toujours::std::purr
et peut ou ne peut pas fournir::purr
.<meow.h>
fournit toujours::purr
et peut ou ne peut pas fournir::std::purr
.Utilisez le formulaire qui est garanti fourni par l'en-tête que vous incluez.
la source
<cmeow>
ni<meow.h>
ne fournit ni::std::purr
ni::purr
mais plutôt une erreur de pré-processeur. Seulement<cstdio>
et / ou<stdio.h>
fournit::std::printf
et / ou::printf
. : Pstrcat
produire::purr
.Non, tu vas bien de toute façon.
L' intention originale était que les en-
<___.h>
têtes seraient les versions C qui mettraient tout dans l'espace de noms global, et les en-<c___>
têtes seraient les versions C ++, qui placent tout dans l'std
espace de noms.En pratique, cependant, les versions C ++ placent également tout dans l'espace de noms global. Et il n'y a pas de consensus clair sur le fait que l'utilisation du
std::
versions est "la bonne chose à faire".Donc, en gros, utilisez celui que vous préférez. Le plus courant est probablement d'utiliser les fonctions de la bibliothèque standard C dans l'espace de noms global (
printf
au lieu destd::printf
), mais il n'y a pas beaucoup de raisons de considérer l'une comme "meilleure" que l'autre.la source
La seule différence est qu'en
std::printf()
ajoutant unestd::
résolution de portée, vous vous sécuriserez contre quelqu'un qui écrit une fonction avec le même nom à l'avenir, ce qui entraînerait un conflit d'espace de noms. Les deux utilisations conduiront exactement aux mêmes appels d'API OS (vous pouvez le vérifier sous Linux en exécutantstrace your_program
).Je trouve très improbable que quelqu'un nomme une fonction comme celle-là, comme
printf()
c'est l'une des fonctions les plus couramment utilisées. De plus, en C ++, lesiostream
s sont préférables aux appels à descstdio
fonctions comme printf.la source
printf
est gravement cassé en C ++ en raison de son manque de frappe forte, le remplacer par une meilleure version est tout à fait naturel.std::printf
est différent demynamespace::printf
, et C ++ me permet explicitement de définir mes propres fonctions dont les noms reflètent ceux des fonctions à l'intérieurstd
. Ce n'est tout simplement pas discutable. Quant à vos affirmations quiprintf
sont efficaces en raison d'une frappe lâche, c'est bien sûr également erroné.printf
n'est même pas particulièrement efficace, il existe de nombreuses implémentations plus efficaces qui sont fortement typées.À partir de la norme C ++ 11:
Donc, si vous utilisez
<cstdio>
, vous pouvez être sûr que ceprintf
sera dansnamespace std
, et donc pas dans l'espace de noms global.L'utilisation d'un espace de noms global crée un conflit de noms. Ce n'est pas une manière C ++.
Par conséquent, j'utilise des en-
<cstdio>
têtes et je vous conseille de le faire.la source
<cstdio>
vous avez la garantie que std :: printf existera, mais il n'y a aucune garantie de la norme si :: printf existera ou non aussi. En fait, dans tous les compilateurs dont j'ai entendu parler :: printf est injecté dans l'espace de noms global lorsque vous incluez<cstdio>
.De ma propre pratique: utilisez des
std::
préfixes. Sinon un jourabs
sera vous mordre très douloureusement au cas où vous en utilisant des points flottants.Non qualifié
abs
fait référence à la fonction définieint
sur certaines plates-formes. Sur d'autres, il est surchargé. Cependantstd::abs
est toujours surchargé pour tous les types.la source
Utiliser juste
printf
sansstd::
pourrait générer des conflits de nom et est considéré comme une mauvaise pratique par de nombreux développeurs C ++. Google est votre ami sur celui-ci, mais voici quelques liens, j'espère que cela vous aideraPourquoi "utiliser l'espace de noms std" est-il considéré comme une mauvaise pratique? http://www.cplusplus.com/forum/beginner/61121/
la source
using namespace std
est une mauvaise pratique mais l'utilisationprintf
sansstd::
qualificatif ne l'est pas.using namespace std;
ce n'est pas mon problème ici. Je ne l'utilise jamais.printf();
etstd::printf();
travailler en C ++ sansusing namespace std;
C'est pourquoi j'ai posté la question.std::printf
cela semble tout simplement étrange.Dans stdio
Cela ne devrait donc pas faire de différence.
la source