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

StackOverflow https://stackoverflow.com/questions/812717

  •  03-07-2019
  •  | 
  •  

Question

Question

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

Je pense utiliser C ++ avec des classes mais sans polymorphisme (pour éviter les vtables). Les principales raisons pour lesquelles je souhaite utiliser C ++ sont les suivantes:

  • Je préfère utiliser les fonctions “en ligne” plutôt que les définitions de macros.
  • Je voudrais utiliser les espaces de noms car je préfixes encombrer le code.
  • Je vois le type C ++ un peu plus sûr, principalement à cause des modèles et de la diffusion verbeuse.
  • J'aime beaucoup les fonctions et les constructeurs surchargés (utilisés pour la diffusion automatique).

Voyez-vous une raison de rester avec C89 lorsque vous développez un matériel très limité (4 Ko de RAM)?

Conclusion

Merci pour vos réponses, elles ont été vraiment utiles!

J'ai pensé au sujet et je vais rester avec C principalement parce que:

  1. Il est plus facile de prévoir le code réel en C, ce qui est vraiment important si vous ne disposez que de 4 Ko de RAM.
  2. Mon équipe est principalement composée de développeurs C, de sorte que les fonctionnalités C ++ avancées ne seront pas utilisées fréquemment.
  3. J'ai trouvé un moyen d'intégrer des fonctions dans mon compilateur C (C89).

Il est difficile d’accepter une réponse car vous avez fourni autant de bonnes réponses. Malheureusement, je ne peux pas créer de wiki et l’accepter. Je vais donc choisir une réponse qui m’a le plus fait réfléchir.

Était-ce utile?

La solution

Deux raisons d'utiliser C sur C ++:

  1. Pour de nombreux processeurs intégrés, il n’existe pas de compilateur C ++ ou vous devez payer un supplément.
  2. Mon expérience est qu’une proportion significative d’ingénieurs en logiciels embarqués n’ont que peu, voire aucune, d’expérience en matière de C ++ - soit en raison de (1), soit parce qu’elle tend à ne pas être enseignée aux diplômes en ingénierie électronique - et que ce serait donc mieux. s'en tenir à ce qu'ils savent.

De plus, la question initiale et un certain nombre de commentaires mentionnent les 4 Ko de RAM . Pour un processeur embarqué typique, la quantité de RAM n’est (généralement) pas liée à la taille du code, car le code est stocké et exécuté à partir de, clignote.

Certes, la quantité d’espace de stockage de code est une chose à garder à l’esprit, mais à mesure que de nouveaux processeurs plus volumineux apparaissent sur le marché, c’est moins un problème que dans le passé, sauf pour les projets les plus sensibles au coût. .

Utilisation d'un sous-ensemble de C ++ pour les systèmes intégrés: il existe maintenant un MISRA C ++

MODIFIER: Voir aussi cette question , ce qui a entraîné un débat sur C vs C ++ pour les applications intégrées systèmes.

Autres conseils

Pour une cible très très restreinte, telle que 4 Ko de RAM, je testais les eaux avec des échantillons avant de consentir de nombreux efforts qui ne peuvent pas être facilement retransférés dans un C simple ANSI. la mise en oeuvre.

Le groupe de travail Embedded C ++ a proposé un sous-ensemble standard du langage et un sous-ensemble standard de la bibliothèque standard. J'ai perdu la trace de cet effort lorsque le journal de l'utilisateur C est mort, malheureusement. On dirait qu’il existe un article dans Wikipedia et que le comité existe toujours.

Dans un environnement intégré, vous devez vraiment faire attention à l’allocation de mémoire. Pour appliquer ce soin, vous devrez peut-être définir l'opérateur global new () et ses amis comme un élément qui ne peut même pas être lié, de sorte que vous sachiez qu'il n'est pas utilisé. Par contre, l'emplacement new sera probablement votre ami s'il est utilisé judicieusement avec un schéma d'allocation stable, thread-safe et à latence garantie.

Les fonctions en ligne ne poseront pas grand problème, sauf si elles sont suffisamment grandes pour avoir été de véritables fonctions. Bien sûr, les macros qu’ils ont remplacées avaient le même problème.

Les modèles, eux aussi, ne peuvent pas poser de problème à moins que leur instanciation ne fonctionne pas. Pour tout modèle que vous utilisez, auditez le code généré (la carte de liens peut avoir suffisamment d’indices) pour vous assurer que seules les instanciations que vous souhaitez utiliser se sont produites.

Un autre problème pouvant survenir est la compatibilité avec votre débogueur. Il n’est pas inhabituel pour un débogueur matériel par ailleurs utilisable d’avoir un support très limité pour l’interaction avec le code source original. Si vous devez effectivement déboguer en assembleur, le nom intéressant de C ++ peut ajouter une confusion supplémentaire à la tâche.

Les RTTI, les conversions dynamiques, les héritages multiples, les polymorphismes lourds et les exceptions entraînent tous des coûts d’exécution très élevés. Quelques-unes des fonctionnalités qui coûtent sur l’ensemble du programme si elles sont utilisées, d’autres augmentent simplement le poids des classes qui en ont besoin. Découvrez la différence et choisissez judicieusement les fonctionnalités avancées en toute connaissance de cause, avec au minimum une analyse coûts-avantages superficielle.

Dans un petit environnement intégré, vous liez directement à un noyau en temps réel ou exécutez directement sur le matériel. Dans les deux cas, vous devez vous assurer que votre code de démarrage à l'exécution gère correctement les tâches de démarrage spécifiques à C ++. Cela peut être aussi simple que de s’assurer d’utiliser les bonnes options d’éditeur de liens, mais comme il est courant d’avoir un contrôle direct sur la source jusqu'au point d’entrée de réinitialisation, vous devrez peut-être vérifier cela pour vous assurer qu’il fait tout. Par exemple, sur une plate-forme ColdFire sur laquelle j'ai travaillé, les outils de développement étaient livrés avec un module CRT0.S dans lequel les initialiseurs C ++ étaient présents, mais mis en commentaire. Si je l’avais utilisé directement depuis la boîte, j’aurais été mystifié par des objets globaux dont les constructeurs n’avaient jamais fonctionné.

En outre, dans un environnement intégré, il est souvent nécessaire d'initialiser les périphériques matériels avant de pouvoir les utiliser. S'il n'y a ni système d'exploitation ni chargeur de démarrage, c'est votre code qui le fait. N'oubliez pas que les constructeurs pour les objets globaux sont exécutés avant que main () ne soit appelé. Vous devrez donc modifier votre CRT0.S local (ou son équivalent) pour obtenir cette initialisation matérielle effectuée avant , les constructeurs globaux eux-mêmes sont appelés. De toute évidence, le sommet de main () est trop tardif.

Non. Toutes les fonctionnalités du langage C ++ susceptibles de poser des problèmes (polymorphisme d'exécution, RTTI, etc.) peuvent être évitées lors du développement intégré. Il existe une communauté de développeurs C ++ incorporés (je me souviens d'avoir lu des chroniques de développeurs incorporés utilisant C ++ dans l'ancien journal des utilisateurs de C / C ++), et je ne peux pas imaginer qu'ils seraient très éloquents si le choix était si mauvais.

Le rapport technique sur les performances C ++ est un excellent guide pour ce genre de chose. Notez qu’il contient une section sur les problèmes de programmation intégrée!

Aussi, ++ sur la mention de C ++ incorporé dans les réponses. La norme ne correspond pas à 100% à mes goûts, mais c’est une bonne référence pour décider quelles parties de C ++ vous allez perdre.

Lors de la programmation pour de petites plates-formes, nous désactivons les exceptions et les RTTI, évitons l'héritage virtuel et portons une attention particulière au nombre de fonctions virtuelles que nous gérons.

Votre ami est la carte de l'éditeur de liens: vérifiez-la fréquemment, et vous repérerez rapidement les sources de code et la mémoire statique.

Après cela, les considérations standard relatives à l'utilisation de la mémoire dynamique s'appliquent: dans un environnement aussi restreint que celui que vous avez mentionné, vous souhaiterez peut-être ne pas utiliser d'allocation dynamique du tout. Parfois, vous pouvez vous en tirer avec des pools de mémoire pour de petites allocations dynamiques, ou "basé sur des images". allocation où vous préaffectez un bloc et jetez le tout plus tard.

Je recommande d'utiliser le compilateur C ++, mais en limitant l'utilisation des fonctionnalités spécifiques à C ++. Vous pouvez programmer comme C en C ++ (le runtime C est inclus dans C ++, bien que dans la plupart des applications incorporées, vous n’utilisiez pas la bibliothèque standard de toute façon).

Vous pouvez continuer et utiliser les classes C ++, etc., juste

  • Limitez votre utilisation des fonctions virtuelles (comme vous l'avez dit)
  • Limitez votre utilisation des modèles
  • Pour une plateforme intégrée, vous souhaiterez remplacer l'opérateur new et / ou utiliser l'emplacement new pour l'allocation de mémoire.

En tant qu’ingénieur en progiciels / systèmes embarqués, je peux vous expliquer en partie pourquoi C est toujours le premier choix par rapport à C ++ et, oui, je parle couramment ces deux logiciels.

1) Certaines cibles sur lesquelles nous développons disposent de 64 Ko de RAM pour le code et les données. Vous devez donc vous assurer que chaque décompte d'octets est correct. Oui, j'ai optimisé le code pour économiser 4 octets, ce qui m'a coûté 2 heures. et c'est en 2008.

2) Chaque fonction de la bibliothèque C est passée en revue avant d’être insérée dans le code final, en raison de la taille limitée. Nous préférons donc que les utilisateurs n’utilisent pas la division (pas de séparateur matériel, il faut donc une grande bibliothèque), malloc (car n’ont pas de tas, toute la mémoire est allouée à partir de la mémoire tampon de données par bloc de 512 octets et doit faire l’objet d’une vérification de code) ou d’une autre pratique orientée objet qui comporte une pénalité importante. N'oubliez pas que chaque fonction de bibliothèque que vous utilisez compte.

3) Avez-vous déjà entendu parler du terme superposition? vous avez si peu d'espace de code que vous devez parfois échanger des éléments avec un autre ensemble de code. Si vous appelez une fonction de bibliothèque, celle-ci doit être résidente. Si vous ne l'utilisez que dans une fonction de superposition, vous perdez beaucoup de temps à utiliser trop de méthodes orientées objet. Donc, ne supposez aucune fonction de la bibliothèque C, encore moins que C ++ soit accepté.

4) Une fusion et un compactage (lorsque la structure de données non alignée dépasse la frontière des mots) sont nécessaires en raison d'une conception matérielle limitée (c'est-à-dire un moteur ECC câblé d'une certaine manière) ou pour faire face à un bogue matériel. Vous ne pouvez pas en supposer trop, donc pourquoi objet l’oriente trop?

5) Pire scénario: éliminer certaines des méthodes orientées objet obligera le développeur à réfléchir avant d’utiliser des ressources susceptibles d’exploser (c’est-à-dire allouer 512 octets sur une pile plutôt qu’à partir d’un tampon de données) et éviter ainsi les pires scénario de cas qui ne sont pas testés ou éliminent le chemin de code entier tous ensemble.

6) Nous utilisons beaucoup d’abstractions pour conserver le matériel des logiciels et rendre le code aussi portable que possible et convivial. L’accès au matériel doit être encapsulé dans une macro ou une fonction intégrée compilée de manière conditionnelle entre différentes plates-formes. Le type de données doit être converti en taille d’octets plutôt qu’en cible, l’utilisation directe du pointeur n’est pas autorisée (certaines plates-formes supposant que la mémoire est mappée en entrée / sortie). identique à la mémoire de données), etc.

Je peux penser à plus, mais vous voyez l'idée. Nous, les gars du firmware, avons une formation orientée objet, mais la tâche d'un système embarqué peut être tellement orientée matériel et de bas niveau, qu'elle n'est ni de haut niveau ni abstinente par nature.

BTW, chaque travail de firmware auquel j'ai participé utilise le contrôle de source, je ne sais pas d'où vous vient cette idée.

-Quelques types de microprogrammes de SanDisk.

  

Mes préférences personnelles sont C car:

     
      
  • Je sais ce que chaque ligne de code fait (et coûte)
  •   
  • Je ne connais pas suffisamment le langage C ++ pour savoir ce que chaque ligne de code fait (et coûte)
  •   

Pourquoi les gens disent-ils cela? Vous ne savez pas ce que chaque ligne de C fait, à moins de vérifier la sortie asm. Il en va de même pour C ++.

Par exemple, quel asm cette déclaration innocente produit-elle:

a[i] = b[j] * c[k];

Cela semble assez innocent, mais un compilateur basé sur gcc produit cet asm pour un micro 8 bits

CLRF 0x1f, ACCESS
RLCF 0xfdb, W, ACCESS
ANDLW 0xfe
RLCF 0x1f, F, ACCESS
MOVWF 0x1e, ACCESS
MOVLW 0xf9
MOVF 0xfdb, W, ACCESS
ADDWF 0x1e, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfa
MOVF 0xfdb, W, ACCESS
ADDWFC 0x1f, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0xfee, 0x1c
NOP
MOVFF 0xfef, 0x1d
NOP
MOVLW 0x1
CLRF 0x1b, ACCESS
RLCF 0xfdb, W, ACCESS
ANDLW 0xfe
RLCF 0x1b, F, ACCESS
MOVWF 0x1a, ACCESS
MOVLW 0xfb
MOVF 0xfdb, W, ACCESS
ADDWF 0x1a, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfc
MOVF 0xfdb, W, ACCESS
ADDWFC 0x1b, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0xfee, 0x18
NOP
MOVFF 0xfef, 0x19
NOP
MOVFF 0x18, 0x8
NOP
MOVFF 0x19, 0x9
NOP
MOVFF 0x1c, 0xd
NOP
MOVFF 0x1d, 0xe
NOP
CALL 0x2142, 0
NOP
MOVFF 0x6, 0x16
NOP
MOVFF 0x7, 0x17
NOP
CLRF 0x15, ACCESS
RLCF 0xfdf, W, ACCESS
ANDLW 0xfe
RLCF 0x15, F, ACCESS
MOVWF 0x14, ACCESS
MOVLW 0xfd
MOVF 0xfdb, W, ACCESS
ADDWF 0x14, W, ACCESS
MOVWF 0xfe9, ACCESS
MOVLW 0xfe
MOVF 0xfdb, W, ACCESS
ADDWFC 0x15, W, ACCESS
MOVWF 0xfea, ACCESS
MOVFF 0x16, 0xfee
NOP
MOVFF 0x17, 0xfed
NOP

Le nombre d'instructions produites dépend énormément de:

  • Les tailles de a, b et c.
  • si ces pointeurs sont stockés sur la pile ou globaux
  • si i, j et k sont sur la pile ou globaux

Cela est particulièrement vrai dans le petit monde intégré, où les processeurs ne sont tout simplement pas configurés pour gérer C. Donc, ma réponse serait que C et C ++ sont aussi mauvais l'un que l'autre, sauf si vous examinez toujours la sortie asm, dans Dans ce cas, ils sont aussi bons l'un que l'autre.

Hugo

J'ai entendu dire que certaines personnes préféraient le langage C au travail embarqué, en raison du fait qu'il est plus simple et donc plus facile de prévoir le code réel qui sera généré.

Personnellement, je pense que l’écriture en C ++ (utilisant des modèles pour la sécurité du type) vous donnerait beaucoup d’avantages et je ne vois aucune raison de ne pas le faire.

Je ne vois aucune raison d'utiliser C au lieu de C ++. Quoi que vous puissiez faire en C, vous pouvez le faire aussi en C ++. Si vous souhaitez éviter les frais généraux liés à VMT, n'utilisez pas de méthodes virtuelles ni de polymorphisme.

Cependant, C ++ peut fournir des idiomes très utiles sans surcharge. Un de mes favoris est RAII. Les classes ne sont pas forcément chères en termes de mémoire ou de performances ...

J'ai écrit du code pour paltform intégré à ARM7 sur IAR Workbench. Je recommande fortement de faire confiance aux modèles pour optimiser la compilation et prédire les chemins. Évitez les castings dynamiques comme peste. Utilisez les caractéristiques techniques suivantes: X & oi = book_result & ct = result & resnum = 4 "rel =" noreferrer "> Conception C ++ moderne .

Je sais, il peut être difficile d’apprendre, mais je suis également convaincu que votre produit bénéficiera de cette approche.

Une bonne raison, parfois seule, est qu’il n’existe toujours pas de compilateur C ++ pour le système intégré spécifique. C’est le cas par exemple des micro-contrôleurs Microchip PIC . Ils sont très faciles à écrire et ils ont un compilateur C gratuit (en fait, une légère variante du C), mais aucun compilateur C ++ n’est en vue.

Pour un système contraint à 4K de RAM, j'utiliserais le C, pas le C ++, juste pour être sûr de voir tout ce qui se passe. Le problème avec C ++ est qu’il est très facile d’utiliser beaucoup plus de ressources (processeur et mémoire) que de regarder le code. (Oh, je vais juste créer un autre BlerfObject pour faire ça ... oups! De mémoire!)

Vous pouvez le faire en C ++, comme déjà mentionné (pas de RTTI, pas de vtables, etc.), mais vous passerez autant de temps à vous assurer que votre utilisation de C ++ ne vous échappe pas comme vous le feriez le équivalent en c.

L’esprit humain gère la complexité en évaluant le plus possible, puis en décidant des points importants à prendre en considération, et en écartant ou en dépréciant le reste. C’est la base même de la stratégie de marque dans le marketing, et en grande partie des icônes.

Pour lutter contre cette tendance, je préfère le C au C ++, car il vous oblige à réfléchir à votre code et à la manière dont il interagit avec le matériel - sans relâche.

De longue expérience, je suis convaincu que C vous oblige à trouver de meilleures solutions aux problèmes, en partie, en vous écartant du chemin sans vous obliger à perdre beaucoup de temps à satisfaire une contrainte que certains auteurs de compilateurs pensaient être. une bonne idée, ou savoir ce qui se passe "sous les couvertures".

Dans cette optique, les langages de bas niveau tels que C vous obligent à consacrer beaucoup de temps au matériel et à la construction de bons ensembles structure / données, tandis que les langages de haut niveau vous obligent à vous demander ce qui se passe. pourquoi vous ne pouvez pas faire quelque chose de parfaitement raisonnable dans votre contexte et votre environnement spécifiques. Battre votre compilateur pour le soumettre (le typage fort est le pire délinquant) n'est pas une utilisation productive du temps.

Je vais probablement bien dans le moule du programmeur - j'aime le contrôle. À mon avis, ce n'est pas un défaut de personnalité pour un programmeur. Le contrôle est ce que nous sommes payés pour faire. Plus précisément, le contrôle FLAWLESSLY. C vous donne beaucoup plus de contrôle que C ++.

Personnellement, avec 4 Ko de mémoire, je dirais que vous n’obtenez pas beaucoup plus de temps en C ++, cochez donc celle qui semble la meilleure combinaison compilateur / exécution pour le travail, car le langage n’a probablement pas beaucoup d’importance. .

Notez qu’il ne s’agit pas non plus de la langue, car la bibliothèque est également importante. Souvent, les bibliothèques C ont une taille minimale légèrement inférieure, mais je peux imaginer qu'une bibliothèque C ++ destinée au développement intégré est réduite, alors assurez-vous de tester.

Certains disent que les compilateurs C peuvent générer un code beaucoup plus efficace car ils ne doivent pas prendre en charge les fonctionnalités C ++ avancées et peuvent donc être plus agressifs dans leurs optimisations.

Bien sûr, dans ce cas, vous pouvez tester les deux compilateurs spécifiques.

C gagne sur la portabilité - parce que les spécifications de langage sont moins ambiguës; offrant ainsi une bien meilleure portabilité et flexibilité entre différents compilateurs, etc. (moins de maux de tête).

Si vous n'utilisez pas les fonctionnalités C ++ pour répondre à un besoin, optez pour C.

  

Voyez-vous une raison de rester avec C89 lorsque vous développez un logiciel très limité?   matériel (4 Ko de RAM)?

Personnellement, s’agissant des applications embarquées (quand je dis embarqué, je ne parle pas de winCE, iPhone, etc., des appareils embarqués surpeuplés aujourd’hui). Je veux dire des périphériques à ressources limitées. Je préfère le C, même si j’ai aussi pas mal travaillé avec C ++.

Par exemple, le périphérique dont vous parlez dispose de 4 Ko de RAM, eh bien, pour cette raison, je ne considérerais pas le C ++. Bien sûr, vous pourrez peut-être concevoir quelque chose de petit en utilisant C ++ et limiter votre utilisation de celle-ci dans votre application, comme l'ont suggéré d'autres publications, mais C ++ "pourrait". potentiellement compliquer / gonfler votre application sous les couvertures.

Allez-vous créer un lien statique? Vous souhaiterez peut-être comparer une application factice statique à l'aide de c ++ vs c. Cela peut vous amener à considérer C à la place. Par contre, si vous êtes capable de construire une application C ++ dans les limites de votre mémoire, allez-y.

IMHO, En général, dans les applications intégrées, j'aime tout savoir sur ce qui se passe. Qui utilise la mémoire / les ressources système, combien et pourquoi? Quand les libèrent-ils?

Lors du développement pour une cible avec X ressources, cpu, mémoire, etc., j'essaie de ne pas trop utiliser ces ressources, car vous ne savez jamais quelles seront les exigences futures, ce qui vous obligera à ajouter plus de code à le projet qui était "supposé" être une simple petite application mais finit par devenir beaucoup plus grosse.

Mon choix est généralement déterminé par la bibliothèque C que nous décidons d'utiliser, qui est sélectionnée en fonction de ce que le périphérique doit faire. Donc, 9/10 fois .. cela finit par être uclibc ou newlib et C. Le noyau que nous utilisons a également une grande influence, ou si nous écrivons notre propre noyau.

C'est aussi un choix de terrain d'entente. La plupart des bons programmeurs C n’ont aucun problème à utiliser le C ++ (même si beaucoup se plaignent tout le temps qu’ils l’utilisent) .. mais je n’ai pas trouvé le contraire vrai (selon mon expérience).

Sur un projet sur lequel nous travaillons (qui implique un noyau de base), la plupart des opérations sont effectuées en C, mais une petite pile réseau a été implémentée en C ++, car il était simplement plus facile et moins problématique d'implémenter la mise en réseau en utilisant C ++. .

Le résultat final est que l’appareil fonctionnera et passera les tests de validation ou non. Si vous pouvez implémenter les contraintes foo in xx et les tas de yy en utilisant le langage z, foncez, utilisez ce qui vous rend plus productif.

Mes préférences personnelles sont C car:

  • Je sais ce que chaque ligne de code fait (et coûte)
  • Je ne connais pas suffisamment le langage C ++ pour savoir ce que chaque ligne de code fait (et coûte)

Oui, je suis à l'aise avec le C ++, mais je ne le connais pas aussi bien que le C standard.

Maintenant, si vous pouvez dire le contraire, utilisez ce que vous savez :) Si cela fonctionne, passe des tests, etc. Quel est le problème?

Combien de ROM / FLASH avez-vous?

4 Ko de RAM peuvent encore signifier qu'il existe des centaines de kilo-octets de FLASH pour stocker le code réel et les données statiques. La RAM de cette taille a tendance à ne s’appliquer qu’aux variables, et si vous faites attention à celles-ci, vous pouvez insérer un programme assez volumineux en termes de lignes de code en mémoire.

Cependant, C ++ tend à rendre plus difficile l'insertion de code et de données dans FLASH, en raison des règles de construction au moment de l'exécution pour les objets. En C, une structure constante peut facilement être placée dans la mémoire FLASH et accessible en tant qu'objet à constante matérielle. En C ++, un objet constant nécessiterait que le compilateur évalue le constructeur au moment de la compilation, ce qui, selon moi, dépasse encore ce qu'un compilateur C ++ peut faire (théoriquement, vous pouvez le faire, mais c'est très très difficile à faire en pratique). .

Donc, dans une "petite RAM", "grand FLASH" genre d'environnement je voudrais aller avec C tout jour. Notez qu'un bon choix intermédiaire est le C99, qui possède la plupart des fonctionnalités C ++ intéressantes pour le code non basé sur les classes.

En général non. C ++ est un super ensemble de C. Cela serait particulièrement vrai pour les nouveaux projets.

Vous êtes sur la bonne voie pour éviter les constructions C ++ qui peuvent coûter cher en temps CPU et en empreinte mémoire.

Notez que certaines choses comme le polymorphisme peuvent être très utiles - ce sont essentiellement des pointeurs de fonction. Si vous en avez besoin, utilisez-les avec sagesse.

En outre, une bonne gestion des exceptions (bien conçue) peut rendre votre application intégrée plus fiable qu'une application gérant des codes d'erreur traditionnels.

La seule raison de préférer C IMHO serait si le compilateur C ++ de votre plate-forme n’était pas en bon état (buggy, optimisation médiocre, etc.).

Le livre C ++ pour les programmeurs de jeux contient des informations relatives au moment où la taille du code sera augmenté en fonction des fonctionnalités de C ++.

Vous avez en ligne dans C99. Vous aimez peut-être les acteurs, mais il est parfois difficile de bien les préparer. Si la dernière raison de ne pas utiliser C est l’espace de nommage, j’en resterais à C89. En effet, vous souhaiterez peut-être le porter sur une plate-forme intégrée légèrement différente. Vous pourrez plus tard commencer à écrire en C ++ sur ce même code. Mais attention, ce qui suit, où C ++ n'est PAS un sur-ensemble de C. Je sais que vous avez dit que vous avez un compilateur C89, mais que la comparaison entre C ++ et C99 est quand même effectuée, car le premier élément, par exemple, est vrai pour tout C depuis K & R; <. / p>

sizeof 'a' > 1 en C, pas en C ++. En C, vous avez des tableaux de longueur variable VLA. Exemple: func (int i) {int a [i] . En C, vous avez les membres du groupe de variables VAM. Exemple: struct {int b; int m [];} .

Je veux juste dire qu’il n’existe pas de système avec "UNLIMITED". Ressources. Tout dans ce monde est limité et CHAQUE application devrait considérer l'utilisation des ressources, qu'il s'agisse d'ASM, de C, de JAVA ou de JavaScript. Les mannequins qui allouent quelques Mbs "juste pour être sûr" rend l'iPhone 7, Pixel et autres appareils extrêmement luggy. Que vous ayez 4 Ko ou 40 Go.

Mais d'un autre côté, opposer le gaspillage de ressources est un temps nécessaire pour économiser ces ressources. S'il faut 1 semaine supplémentaire pour écrire une chose simple en C, économiser quelques ticks et quelques octets au lieu d'utiliser C ++ déjà implémenté, testé et distribué. Pourquoi s'embêter? C'est comme acheter un hub USB. oui vous pouvez le faire vous-même mais est-ce que ça va être mieux? plus fiable? moins cher si vous comptez votre temps?

Juste une pensée de côté - même le pouvoir de votre prise n’est pas illimité. Essayez de chercher d'où ça vient et vous verrez surtout que c'est de brûler quelque chose. La loi de l'énergie et de la matière est toujours valable: aucune matière ou énergie n'apparaît ou ne disparaît mais se transforme.

Pour les problèmes d’allocation de mémoire, je peux recommander l’utilisation de Quantum Platform et de son approche à la machine à états, car elle alloue tout ce dont vous avez besoin au moment de l’initialisation. Cela permet également de réduire les problèmes de conflit.

Ce produit fonctionne à la fois en C et en C ++.

Cela dépend du compilateur.

Tous les compilateurs intégrés n’implémentent pas tout le C ++ et, même s’ils le font, ils ne sont peut-être pas efficaces pour éviter le gonflement du code (ce qui est toujours un risque avec les modèles). Testez-le avec quelques programmes plus petits, voyez si vous rencontrez des problèmes.

Mais avec un bon compilateur, non, il n'y a aucune raison de ne pas utiliser C ++.

Je viens juste de trouver un exemple d'utilisation d'ISO C ++ pour le développement intégré, ce qui pourrait être intéressant pour quelqu'un qui prend la décision d'utiliser C ++ ou C à chaque fois.

Il a été fourni par Bjarne Stroustrup sur sa page d'accueil :

Pour savoir comment utiliser ISO C ++ pour la programmation de systèmes embarqués sérieux, voir Normes de codage C ++ pour véhicules aériens JSF .

Répondez différemment à un aspect différent de la question:

"malloc"

Certaines réponses précédentes en parlent assez souvent. Pourquoi pensez-vous même que cet appel existe? Pour une plate-forme vraiment petite, malloc a tendance à être indisponible ou définitivement optionnel. L'implémentation dynamique de la mémoire a tendance à avoir du sens lorsque vous avez un RTOS au bas de votre système - mais jusque-là, c'est purement dangereux.

Vous pouvez aller très loin sans cela. Il suffit de penser à tous les anciens programmes FORTRAN qui n’avaient même pas une pile appropriée pour les variables locales ...

Il existe un grand nombre de fabricants de contrôleurs dans le monde. Lorsque vous examinez leurs conceptions et les jeux d'instructions à utiliser pour la configuration, vous risquez de rencontrer de nombreux problèmes. Le principal inconvénient du langage d'assemblage est que cela dépend de la machine / de l'architecture. C’est vraiment énorme de demander à un développeur de connaître par cœur toutes les instructions qui y sont définies pour coder différents contrôleurs. C’est pourquoi C est devenu plus populaire dans le développement intégré car il est assez puissant pour extraire les algorithmes et les structures de données des détails liés au matériel, rendant le code source portable sur une grande variété de matériel cible, un langage indépendant de l’architecture et très facile à utiliser. convertir et maintenir le code. Cependant, nous constatons que certains langages de haut niveau (orientés objet) tels que C, C ++, Python, Java, etc. évoluent suffisamment pour les rendre sous le radar du développement de systèmes intégrés.

Sur un système aussi limité. Allez juste pour l'assembleur. Vous donne un contrôle total sur tous les aspects, sans aucun frais supplémentaire.

Probablement beaucoup plus rapide aussi car beaucoup de compilateurs intégrés ne sont pas les meilleurs optimiseurs (surtout si on le compare à des compilateurs de pointe comme ceux que nous avons pour le bureau (Intel, Visual Studio, etc.))

"ouais ouais ... mais c est réutilisable et ...". Sur un système aussi limité, il est probable que vous n'utiliserez de toute façon pas une grande partie de ce code sur un système différent. Sur le même système, l’assembleur est tout aussi réutilisable.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top