Utiliser / Mélanger C en code C++?
l'utilisation de C en c++ est-elle mauvaise?
beaucoup de gens m'ont dit que l'utilisation du C en c++ est mauvaise parce que ce n'est pas aussi sûr, et cela nécessite plus de gestion de la mémoire. Je n'arrête pas de leur dire que tant que tu sais ce que tu fais, et que tu effaces tes "nouveaux"s et libères tes "malloc"s, alors C n'est pas un problème.
je suis actuellement sur un forum où une dispute sur std::string
vs char*
. Certaines personnes disent que l'attribution d'un simple char*
bloc de mémoire est plus efficace, et tant que tu le désalloques, c'est bon. D'un autre côté, nous avons des gens qui disent que std::string
est supérieur parce qu'il n'y a pas de gestion de mémoire impliquée mais est moins efficace.
donc la question principale ici est:
- Est un mélange de C/C++ mauvais? Ne devriez-vous utiliser 100% C++ que lorsque vous codez C++?
toute réponse serait appréciée!
12 réponses
je continue à leur dire que tant que vous savez ce que vous faites, et que vous supprimez vos nouvelles et libérez vos malloc, alors C n'est pas un problème.
C'est vrai; si vous êtes extraordinairement prudent et vous assurez que vous nettoyez manuellement les choses, alors ce n'est pas un problème. Mais avez-vous vraiment le temps de le faire? Chaque appel à new
lancer std::bad_alloc
. Avez-vous toujours catch tous les exception qui peut être jetée et nettoyée manuellement toutes les ressources?
j'avais danger pour deviner la réponse est "non", car il est très fastidieux à écrire du code comme ça et il est difficile d'être absolument sûr que le code écrit comme ça, c'est correct, même dans le cas de rares échecs.
si la réponse est" oui", alors pourquoi perdez-vous autant de temps à vous soucier de la gestion des ressources? Les idiomes C++ comme gestion des ressources liée à la portée (SBRM; plus connu sous le nom d'acquisition de ressources is initialization (RAII)) et les bibliothèques comme la bibliothèque de modèle standard sont là pour vous aider à écrire le code correct plus facilement. Pourquoi faire les choses à la dure quand vous n'avez pas à?
ne devriez-vous utiliser 100% C++ que lorsque vous codez C++?
Oui, mais si il n'y est une bibliothèque C qui fait quelque chose dont vous avez besoin, ou si vous avez hérité C code que vous souhaitez utiliser, vous pouvez certainement utiliser ce code; assurez-vous simplement d'être prudent. Souvent la façon la plus propre d'interopérer avec du code C est d'écrire un C++ wrapper autour d'elle.
je crois fermement que votre question n'a rien à voir avec C ou C++. Votre question porte sur le commerce de l'efficacité douteuse pour la sécurité. Oui, C peut être plus efficace. Mais combien plus efficace? Et que faites-vous payer pour cela? Voici les questions auxquelles vous devez répondre. Dans la plupart des cas, les chaînes de caractères par opposition aux chaînes de caractères par opposition aux const* sont invisibles. Si vous développez une application extrêmement critique en termes d'efficacité, pourquoi ne pas la coder en C en premier lieu?
je suis vraiment surpris par la polarisation des réponses et des commentaires.
Dans mes yeux, la réponse est assez simple:
lors de l'écriture D'un projet C++, utilisez C++, évitez C ( et la famille) et collez à la bibliothèque Standard et STL. Assurer une interface c++ homogène (c'est un projet C++ Après tout!) Lors de l'utilisation d'un projet externe en C, qui se trouve être écrit en C, bien sûr, vous pouvez l'utiliser. (voir les exemples ci-dessous)
deux le premier des exemples:
Écrire un programme c++ / bibliothèque qui fait des calculs scientifiques. J'utiliserais certainement GSL (GNU Scientific Library), et c'est écrit en C. Il n'y a que quelques mises en garde (comme l'initialisation spécialisée et les fonctions libres pour les structures et les fonctions spécifiques au sein de GSL), qui peuvent être absorbées dans un
std::unique_ptr
typedef. Il y a aussi la question de la gestion des erreurs: la vérification des codes d'erreur peut être abstraite dans un mécanisme d'exception si nécessaire/voulu, ou vous pouvez conserver les codes d'erreur contenue dans les fonctions de calcul. GSL a une façon de configurer un gestionnaire d'erreurs, j'imagine que d'autres bibliothèques C ont une telle fonctionnalité.Écrire un programme C++ en utilisant L'API Win32, qui est horriblement basée sur C. Je parle de l'utilisation de L'API légère, comme lire les fichiers dans un répertoire, vérifier si un fichier existe, etc., pas GDI lourde+ ou d'autres choses. J'aime envelopper toutes les fonctions C que L'API Win32 expose dans nice C++ fonctions de style, peut-être avec les exceptions nécessaires et en retournant un
std::string
au lieu d'avoir à passer unchar*
buffer comme argument.
je comprends que les deux exemples sont tout à fait... peu profonde... mais je pense qu'ils expriment une idée assez générale.
la meilleure question ici est, pourquoi utiliser C? La performance? Premièrement, je crois qu'il n'y a pas de différence de rendement mesurable pour un programme ayant la même fonction. Deuxièmement, vous devriez profiler et prouver que pour votre cas spécifique, C++ est plus lent. Troisièmement, vous abandonnez une énorme quantité de sécurité d'application en utilisant C au lieu de C++.
reformuler l'argument par rapport à std:: string vs char *.
std:: string ne va pas être plus lent que char * (pour heap char*); de nombreuses implémentations sont beaucoup plus rapides parce qu'elles utilisent le pool de mémoire privé. Et de toute façon la robustesse de std:: string l'emporte de loin sur tout (improbable) coup de perf
La réponse est, bien sûr: ça dépend.
généralement vous voulez éviter de mélanger des choses qui peuvent causer de la confusion, qui peuvent conduire à des bugs difficiles à trouver. Juste parce que "tu sais ce que tu fais" ne veut pas dire que la prochaine personne à toucher ton code saura ce que tu faisais. Si vous développez du code que vous seul utiliserez jamais, alors c'est probablement d'accord, mais c'est rarement le cas.
utiliser C pour la performance est très bien si vous êtes prudent. Mais vous ne devriez le faire que si vous savez que vous avez besoin de la performance. L'optimisation prématurée de bas niveau est le travail du diable.
c'est un cas très rare où l'utilisation de char* sur std::string vous donnera tous les avantages de performance notables, et il ne vaut la peine de la gestion de la mémoire tracasse dans les cas où il le fait à coup sûr.
Oui c'est mal de mélange de C et de C++, toute la raison n'a rien à voir avec la performance ou de sécurité:
C'est une mauvaise cause d'une maintenabilité:
* un programmeur C++ s'attend à ce que tout le code se comporte comme C++.
* un programmeur C s'attend à ce que tous les codes se comportent comme C.
donc quand vous mélangez C++ et C, vous brisez les attentes des deux programmeurs sur la façon dont les choses devraient fonctionner.
La réponse est simple, ici, c'est profil; déterminer ce qui fonctionne le mieux dans votre cas et l'utiliser à bon escient!
l'utilisation de C en c++ est-elle mauvaise?
bien qu'une question subjective: à mon avis, prendre de grandes mesures pour éviter d'utiliser c dans les programmes C++.
beaucoup de gens m'ont dit que l'utilisation du C en c++ est mauvaise parce que ce n'est pas aussi sûr, et cela nécessite plus de gestion de la mémoire. Je n'arrête pas de leur dire que tant que tu sais ce que tu fais, et que tu effaces tes nouvelles et libères tes malloc, alors C n'est pas un problème.
vous réintroduisez les déficiences et les dangers c++ a été conçu pour surmonter, et ce n'est pas la façon dont les choses sont faites dans les programmes c++.
je vérifie/rejette/réécrit régulièrement le code qui entre les codebases qui est "c avec C++ features", ou "c++ avec c features". j'ai même aller jusqu'à changer de malloc, free, etc. affirmer dans les espaces de noms racine (entre autres choses).
je suis actuellement sur un forum où une discussion sur std::string vs. A char* a lieu. Certains disent que la répartition un simple bloc mémoire char* est plus efficace, et tant que vous le désactivez, c'est parfait. D'un autre côté, nous avons des gens qui disent que std::string est supérieur parce qu'il n'a pas de gestion de mémoire impliquée mais est moins efficace.
il y a plus d'options pour représenter une chaîne en c++ que std::string.
à mon avis, il est tout à fait valide de créer une nouvelle classe qui représente une chaîne et sert un but particulier, ou suit des contrats supplémentaires (lorsque nécessaire). une partie des contrats de ces représentations de chaînes de caractères sont (bien sûr) qu'ils gèrent leurs propres ressources en utilisant new[]/delete[]
lorsque la mémoire dynamique est utilisée.
si l'efficacité est plus important et std::string
est moins qu'idéal pour une tâche spécifique, alors c++ est assez puissant pour exprimer votre intention pour ces cas spécifiques en créant une interface spécialisée en c++. il existe de nombreux cas où cela est acceptable (imo), mais cela ne vaut pas toujours la peine d'investir du temps. en tout event, c'est plus facile à gérer que d'intégrer des idiomes/styles/dangers en c++ dans les programmes.
donc la question principale ici est: Est-ce que mixer C / c++ est mauvais? Votre code C++ ne devrait-il être utilisé qu'à 100%?
il est préférable de créer des solutions basées sur des objets réutilisables pour vos besoins. les dangers dans l'exemple fourni peuvent être complètement encapsulés (si cette optimisation vaut vraiment l'investissement de temps), et être écrits pour utiliser les idiomes c++, sans perte de performance et avec une meilleure maintenabilité.
Dans le cas spécifique de l' string
contre const char *
, vous devez utiliser nue const char *
pour toutes les variables qui détiennent constantes de chaîne (et constantes de chaîne de caractères), conversion en string
uniquement lors du passage à une API qui requiert string
. Faire ceci de manière cohérente peut éliminer un nombre énorme de constructeurs globaux, ne cause pas de maux de tête d'allocation de mémoire (puisque les constantes de chaîne sont des données permanentes, constantes) et IMO rend en fait le code plus clair - vous voyez const char *
, vous savez que ça va être une constante de chaîne.
si vous parlez de techniques, je serais prudent de dire que faire ce qui précède est correct.
écrire des programmes C++ en utilisant des techniques d'organisation de programme de style C posera probablement beaucoup de problèmes de maintenabilité. En général, le programmeur ignore bon nombre des avantages qu'offre un langage orienté objet. Simplement parce qu'une grande partie de la syntaxe C est valide C++ et de nombreuses techniques de transfert de codage ne signifie pas que vous devez les faire en C++.
cela dit, en utilisant C les fonctions et les choses ne sont pas un problème, tant que vous faites attention à leur utilisation. Dans certains cas, vous devez.
eh Bien, je suis dans une situation étrange. Je travaille sur un système qui est supposé être en C++ (le compilateur C++ est utilisé et le terme c++ est utilisé), mais tout est écrit en C. C'est très frustrant, parce qu'il arrive à un point où je dois "prouver" que C++ est meilleur à utiliser que C, même si nous codons en C++. C'était l'enfer quand j'ai lancé std::string. Mon point de vue est que tout commence maintenant à être encombré (mélange de C et C++). Il existe de rares cas d'erreur manutention. En fait,je pense que je peux compter trois déclarations d'essai du système. Le code est confus, les fuites de mémoire sont proéminentes et trouver une erreur est une aiguille dans une botte de foin. Il y a des centaines de lignes de code qui peuvent être remplacées par des fonctions C++. Je dirais qu'écrire le code est plus efficace, plus propre et plus facile à comprendre.
D'après mon expérience, Oui bien sûr vous pouvez mélanger C et c++. Vous pouvez très bien faire ce que vous voulez, mais la maintenance, débogage et effectivement déterminer ce qui se passe devient un problème. C'est facile de dire que vous allez nettoyer vos allocations de mémoire, mais peut-être que quelqu'un d'autre utilise votre code et ne le fait pas. Peut-être que tu oublies de le faire et que tu perds des heures à trouver des insectes stupides, au lieu d'utiliser ce temps pour faire quelque chose de productif. Je ne pense même pas qu'il devrait y avoir une dispute. Quand vous faites C++, C++. Quand vous faites C, faites c