Obsolète Fonctions
L'insécurité
Un parfait exemple d'une telle fonction gets(), car il n'y a aucun moyen de savoir comment big le tampon de destination est. Par conséquent, tout programme qui prend en entrée à l'aide de gets() a une vulnérabilité de dépassement de tampon. Pour des raisons similaires, on devrait utiliser strncpy() à la place de la fonction strcpy() et strncat() à la place de strcat().
Encore d'autres exemples comprennent la tmpfile() et mktemp() fonction en raison de problèmes de sécurité potentiels avec d'écraser les fichiers temporaires et qui sont remplacées par le plus sécurisé mkstemp() fonction.
Non Réentrant
D'autres exemples comprennent gethostbyaddr() et gethostbyname() , qui sont non réentrant (et, par conséquent, de ne pas être thread-safe) et ont été remplacés par le réentrant getaddrinfo() et freeaddrinfo().
Vous avez peut-être remarqué un modèle ici... soit le manque de sécurité (éventuellement en omettant d'inclure suffisamment d'informations dans la signature, éventuellement, de mettre en œuvre de manière sécurisée) ou non réentrance sont des sources communes de la dépréciation.
Obsolète, Non Portable
Quelques autres fonctions simplement devenu obsolète car ils font double emploi avec les fonctionnalités et ne sont pas aussi portable que d'autres variantes. Par exemple, bzero() est dépréciée en faveur de memset().
Fil de Sécurité et de re-ouverture
Vous avez demandé, dans votre post, à propos de la sécurité des threads et de la re-ouverture. Il y a une légère différence. Une fonction est réentrant si elle n'utilise pas tout partagé, mutable état. Ainsi, par exemple, si toutes les informations dont il a besoin est transmis à la fonction, et toutes les tampons nécessaires sont également transmis à la fonction (plutôt que partagée par tous les appels à la fonction), puis il est réentrant. Cela signifie que les différents threads, en utilisant des paramètres indépendants, ne risque pas accidentellement l'état de partage. La réentrance est un renforcement de la garantie de la sécurité des threads. Une fonction est thread-safe si elle peut être utilisée par plusieurs threads simultanément. Une fonction est thread-safe si:
- Il est réentrant (c'est à dire qu'il ne partage pas tout de l'état entre les appels), ou:
- Il est non réentrant, mais il utilise la synchronisation/verrouillage comme nécessaire pour l'état partagé.
En général, dans la Single UNIX Specification et IEEE 1003.1 (c'est à dire "POSIX"), toute fonction qui n'est pas garanti d'être réentrant n'est pas garanti d'être thread-safe. Donc, en d'autres termes, seules les fonctions qui sont garantis d'être réentrant peut-être de façon portable utilisé dans les applications multithread (sans verrouillage externe). Cela ne signifie pas, cependant, que les implémentations de ces normes ne peuvent pas choisir de faire un non-fonction réentrante des threads. Par exemple, Linux ajoute fréquemment la synchronisation non-fonctions réentrantes afin d'ajouter une garantie (au-delà de celle de la Single UNIX Specification) de threadsafety.
Des chaînes de caractères (et de la Mémoire tampon, en Général)
Vous m'avez également demandé si il y a un vice fondamental de cordes/tableaux. Certains diront que c'est le cas, mais je dirais que non, il n'y a pas de faille fondamentale dans la langue. C et C++ vous obliger à passer la longueur/la capacité d'un tableau séparément (ce n'est pas une ".la longueur de la propriété" comme dans quelques autres langues). Ce n'est pas un défaut, per se. Tout le C et le C++ développeur peut écrire du code correct, tout simplement en passant la longueur comme un paramètre en cas de besoin. Le problème est que plusieurs Api que nécessaire, cette information a omis de spécifier que c'est un paramètre. Ou supposé que certains MAX_BUFFER_SIZE constante serait utilisé. Ces Api sont maintenant obsolètes et remplacés par d'autres Api qui permettent le tableau/tampon/string taille spécifiée.
Scanf (En Réponse à Votre Dernière Question)
Personnellement, j'utilise le C++ iostreams bibliothèque (std::cin, std::cout << et >> les opérateurs, std::getline, std::istringstream, std::ostringstream, etc.), donc je n'ai généralement pas le gérer. Si je ont été forcés à utiliser pur C, si, je serais personnellement utiliser fgetc() ou getchar() en combinaison avec strtol(), strtoul(), etc. et d'analyser les choses manuellement, puisque je ne suis pas un grand fan de varargs ou des chaînes de format. Cela dit, à ma connaissance, il n'y a pas de problème avec [f]scanf(), [f]printf(), etc. aussi longtemps que vous le métier de chaînes de format vous-même, vous ne laissez jamais passer arbitraire des chaînes de format ou de permettre l'entrée d'utilisateur pour être utilisés comme des chaînes de format, et que vous utilisez la mise en forme des macros définies dans <inttypes.h> le cas échéant. (Remarque, snprintf() doit être utilisé à la place de sprintf(), mais qui a à voir avec omettant de spécifier la taille de la mémoire tampon de destination et non pas de l'utilisation de chaînes de format). Je tiens également à souligner que, en C++, boost::format fournit printf comme le formatage sans varargs.