91 votes

Y a-t-il une raison d'utiliser C au lieu de C ++ pour le développement intégré?

Question

J'ai deux compilateurs sur mon matériel C++ et C89

Je suis en train de réfléchir à l'aide de C++ avec les classes, mais sans polymorphisme (pour éviter les vtables). La raison principale que je voudrais utiliser C++ sont:

  • Je préfère utiliser "inline" fonctions à la place des définitions de macros.
  • J'aimerais utiliser des espaces de noms que je les préfixes de l'encombrement du code.
  • Je vois C++ de type un peu plus sûr en raison principalement de modèles et détaillé de la coulée.
  • J'aime vraiment les fonctions surchargées et les constructeurs (utilisé pour le réglage automatique de moulage).

Voyez-vous une raison de rester avec C89 développement pour très limitée sur le matériel (4 ko de RAM)?

Conclusion

Merci pour vos réponses, ils ont été vraiment utile!

J'ai bien le sujet et je m'en tiendrai à C principalement parce que:

  1. Il est plus facile de prédire les code en C et c'est vraiment important si vous avez seulement 4 ko de ram.
  2. Mon équipe est composée de développeurs C surtout pour l'avance des fonctionnalités de C++ ne sera pas fréquemment utilisé.
  3. J'ai trouvé un moyen de fonctions inline dans mon compilateur C (C89).

Il est difficile d'accepter une réponse que vous avez fourni tant de bonnes réponses. Malheureusement je ne peux pas créer un wiki et de l'accepter, je vais donc choisir une seule réponse qui m'a fait penser à la plupart.

73voto

RBerteig Points 23331

Pour un très à ressources limitées cible, telle qu'4 ko de RAM, j'avais tester les eaux avec quelques échantillons avant de commettre beaucoup d'efforts qui ne peuvent pas être facilement porté en arrière dans un pur C ANSI mise en œuvre.

L'Embedded C++ groupe de travail a proposé une norme sous-ensemble de la langue standard et un sous-ensemble de la bibliothèque standard pour aller avec elle. J'ai perdu la trace de l'effort lors de la C de l'Utilisateur du Journal est mort, malheureusement. Il semble qu'il y est un article de Wikipédia, et que le comité existe toujours.

Dans un environnement embarqué, vous devez vraiment être prudent quant à l'allocation de la mémoire. Pour faire valoir ce que de soins, vous devrez peut-être définir le global operator new() et ses amis pour quelque chose qui ne peut pas même être liées, de sorte que vous savez qu'il n'est pas utilisé. Placement new sur l'autre main est susceptible d'être votre ami, lorsqu'il est utilisé judicieusement avec une stable, thread-safe, et la latence de la garantie schéma d'allocation.

Inline fonctions ne cause pas trop de problème, sauf si elles sont suffisamment grosses pour qu'elles devraient avoir été de véritables fonctions en premier lieu. Bien sûr, les macros à leur remplacement avait le même problème.

Modèles, trop, ne peut pas poser de problème, sauf si leur instanciation s'exécute amok. Pour n'importe quel modèle que vous utilisez, à la vérification de votre code généré (le lien de la carte peut avoir suffisamment d'indices) pour s'assurer que seuls les instanciations que vous souhaitez utiliser est arrivé.

Un autre problème qui peut se poser est celle de la compatibilité avec votre débogueur. Il n'est pas inhabituel pour un matériel utilisable débogueur ont très peu de soutien pour l'interaction avec le code source d'origine. Si vous devez déboguer dans l'assemblée, puis le nom intéressant déformation de C++ peut qu'ajouter de la confusion à la tâche.

RTTI, dynamique jette, l'héritage multiple, lourd polymorphisme, et d'exceptions près, venir avec une certaine quantité d'exécution coût de leur utilisation. Quelques-unes de ces caractéristiques niveau que les coûts sur l'ensemble du programme, s'ils sont utilisés, d'autres se contentent d'augmenter le poids des classes qui en ont besoin. Connaître la différence, et de choisir les fonctionnalités avancées à bon escient avec pleine connaissance d'au moins un rapide coup d'une analyse coût/bénéfice.

Dans un petit environnement embarqué vous serez soit en les reliant directement à un noyau temps réel ou en exécutant directement sur le matériel. De toute façon, vous aurez besoin pour faire certain que votre runtime code de démarrage des poignées de C++ spécifiques de démarrage tâches correctement. Cela pourrait être aussi simple que de s'assurer d'utiliser les options du linker, mais depuis qu'il est commun d'avoir un contrôle direct sur la source de la puissance sur réinitialiser le point d'entrée, vous pourriez avoir besoin de vérification, assurez-vous qu'il s'occupe de tout. Par exemple, sur un ColdFire plate-forme, j'ai travaillé sur, les outils de dev livré avec un CRT0.S module qui a eu le C++ initialiseurs présent, mais en commentaire. Si j'avais utilisé directement à partir de la boîte, j'aurais été mystifié par des objets globaux dont les constructeurs n'avait jamais fonctionner à tous.

Aussi, dans un environnement embarqué, il est souvent nécessaire d'initialiser les périphériques matériels avant qu'ils puissent être utilisés, et si il n'y a pas d'OS et pas de chargeur de démarrage, alors il est de votre code qui le fait. Vous aurez besoin de se rappeler que les constructeurs pour les objets globaux sont exécutés avant main() est appelé ainsi, vous aurez besoin de modifier votre local CRT0.S (ou son équivalent) pour obtenir que l'initialisation du matériel de fait avant le mondial des constructeurs eux-mêmes sont appelés. Évidemment, le haut de l' main() est trop tard.

55voto

Steve Melnikoff Points 1694

Pour deux raisons, à l'aide de C sur C++:

  1. Pour un grand nombre de processeurs embarqués, soit il n'y a pas de compilateur C++, ou que vous avez à payer un supplément pour cela.
  2. Mon expérience est que l'un des importants proportion des logiciels embarqués, les ingénieurs ont peu ou pas d'expérience de C++ -- soit en raison de (1), ou parce qu'il a tendance à ne pas être enseignés sur l'électronique engineeering degrés -- et donc, il serait préférable de coller avec ce qu'ils savent.

Aussi, la question d'origine, et un certain nombre de commentaires, oublier les 4 Ko de RAM. Pour un type intégré processeur, la quantité de RAM est (principalement) sans rapport avec la taille du code, le code est stocké et exécuté à partir d', flash.

Certes, la quantité de code de l'espace de stockage est quelque chose à garder à l'esprit, mais sous une forme nouvelle, plus large, processeurs apparaissent sur le marché, c'est moins un problème qu'elle ne l'habitude d'être pour tous, mais les plus sensibles aux coûts des projets.

Sur l'utilisation d'un sous-ensemble de C++ pour une utilisation avec les systèmes embarqués: il y a maintenant un MISRA C++ standard, qui peut être en valeur un regard.

EDIT: Voir aussi cette question, qui a conduit à un débat sur le C vs C++ pour les systèmes embarqués.

27voto

Harper Shelby Points 13395

N ° Les fonctionnalités de langage C++ qui pourrait causer des problèmes (polymorphisme de duree, RTTI, etc.) peuvent être évités en faisant développement embarqué. Il y a une communauté de développeurs de C++ embarqués (je me souviens avoir lu des colonnes par les développeurs de systèmes embarqués à l’aide de C++ dans le vieux C/C++ Users' Journal), et je ne peux pas imaginer qu’ils seraient très bruyante si le choix était si mauvais.

22voto

leander Points 6363

Le Rapport Technique sur les Performances de C++ est un excellent guide pour ce genre de chose. Notez qu'il dispose d'une section sur la programmation embarquée préoccupations!

Aussi, ++ sur la mention de l'Embedded C++ dans les réponses. La norme n'est pas à 100% à mon goût, mais c'est un bon peu de référence au moment de décider quelles parties de C++, vous pourriez tomber.

Alors que la programmation pour les petites plates-formes, nous désactivons les exceptions et les RTTI, éviter l'héritage virtuel, et l'attention au nombre de fonctions virtuelles, nous avons traînent.

Votre ami est le linker carte, bien que: vérifier fréquemment, et vous pourrez apercevoir des sources de code et de mémoire statique gonfler rapidement.

Après cela, la dynamique de l'utilisation de la mémoire considérations s'appliquent: dans un environnement aussi restreint que celui que vous mentionnez, vous souhaitez peut-être pas utiliser les allocations dynamiques. Parfois, vous pouvez vous en sortir avec des pools de mémoire pour les petits dynamique allocations, ou "basé sur le cadre de" l'allocation de l'endroit où vous préallouer un bloc et jetez le tout plus tard.

18voto

arke Points 971

Je recommande d'utiliser le compilateur C++, mais de limiter votre utilisation de C++ caractéristiques spécifiques. Vous pouvez programmer comme C en C++ (le runtime C est inclus lorsque vous faites C++, mais dans la plupart des applications embarquées vous ne faites pas usage de la bibliothèque standard de toute façon).

Vous pouvez aller de l'avant et à l'utilisation des classes C++, etc., juste

  • Limiter votre utilisation de fonctions virtuelles (comme vous l'avez dit)
  • Limiter votre utilisation de modèles
  • Pour une plate-forme intégrée, vous aurez envie de remplacer l'opérateur new et/ou de l'utilisation du placement de nouvelles pour l'allocation de mémoire.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X