web-dev-qa-db-fra.com

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 pense à utiliser C++ avec des classes mais sans polymorphisme (pour éviter les vtables). Les principales raisons pour lesquelles j'aimerais utiliser C++ sont:

  • Je préfère utiliser des fonctions "en ligne" plutôt que des définitions de macro.
  • Je voudrais utiliser des espaces de noms car mes préfixes encombrent le code.
  • Je vois C++ un type de bit plus sûr principalement à cause des modèles et du casting verbeux.
  • J'aime vraiment les fonctions et les constructeurs surchargés (utilisés pour le casting automatique).

Voyez-vous une raison de rester avec C89 lors du développement pour du matériel très limité (4 Ko de RAM)?

Conclusion

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

J'ai réfléchi au sujet et je vais m'en tenir à C principalement parce que:

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

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

77
Piotr Czapla

Deux raisons d'utiliser C sur C++:

  1. Pour de nombreux processeurs intégrés, soit il n'y a pas de compilateur C++, soit vous devez payer un supplément pour cela.
  2. D'après mon expérience, une proportion importante d'ingénieurs en logiciels embarqués ont peu ou pas d'expérience du C++ - soit à cause de (1), soit parce qu'il a tendance à ne pas être enseigné sur les diplômes d'ingénierie électronique - et il serait donc préférable de s'en tenir à ce qu'ils savent.

De plus, la question d'origine et un certain nombre de commentaires mentionnent les 4 Kb de [~ # ~] bélier [~ # ~]. Pour un processeur intégré typique, la quantité de RAM est (principalement) sans rapport avec la taille du code, car le code est stocké et exécuté à partir de Flash).

Certes, la quantité d'espace de stockage de code est quelque chose à garder à l'esprit, mais à mesure que de nouveaux processeurs, plus spacieux, apparaissent sur le marché, c'est moins un problème qu'auparavant pour tous les projets, sauf les plus sensibles aux coûts.

Sur l'utilisation d'un sous-ensemble de C++ pour une utilisation avec des systèmes embarqués: il existe maintenant une norme MISRA C++ , qui peut valoir le coup d'œil.

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

42
Steve Melnikoff

Pour une cible très très limitée en ressources, telle que 4Ko de RAM, je testerais les eaux avec quelques échantillons avant de faire beaucoup d'efforts qui ne peuvent pas être facilement retransporté dans une implémentation ANSI C pure.

Le groupe de travail Embedded C++ a proposé un sous-ensemble standard du langage et un sous-ensemble standard de la bibliothèque standard pour l'accompagner. J'ai perdu la trace de cet effort lorsque le Journal de l'utilisateur C est mort, malheureusement. Il semble qu'il y ait un article sur Wikipedia , et que le comité existe toujours.

Dans un environnement embarqué, vous devez vraiment faire attention à l'allocation de mémoire. Pour appliquer ce soin, vous devrez peut-être définir la operator new() globale et ses amis à quelque chose qui ne peut même pas être lié afin que vous sachiez qu'elle n'est pas utilisée. Le placement new, d'autre part, est probablement votre ami, lorsqu'il est utilisé judicieusement avec un schéma d'allocation stable, thread-safe et à latence garantie.

Les fonctions intégrées ne causeront pas beaucoup de problèmes, sauf si elles sont suffisamment grandes pour qu'elles auraient dû être de vraies fonctions en premier lieu. Bien sûr, les macros qu'elles remplaçaient avaient le même problème.

Les modèles, eux aussi, ne peuvent pas poser de problème à moins que leur instanciation ne tourne mal. Pour tout modèle que vous utilisez, auditez votre code généré (le mappage de liens peut avoir suffisamment d'indices) pour vous assurer que seules les instanciations que vous aviez l'intention d'utiliser se sont produites.

Un autre problème qui peut survenir est la compatibilité avec votre débogueur. Il n'est pas rare qu'un débogueur matériel autrement utilisable ait une prise en charge très limitée de l'interaction avec le code source d'origine. Si vous devez effectivement déboguer dans Assembly, le mangling de nom intéressant de C++ peut ajouter une confusion supplémentaire à la tâche.

RTTI, transtypages dynamiques, héritage multiple, polymorphisme lourd et exceptions s'accompagnent tous d'un certain coût d'exécution pour leur utilisation. Certains de ces niveaux de fonctionnalités qui coûtent sur l'ensemble du programme s'ils sont utilisés, d'autres augmentent simplement le poids des classes qui en ont besoin. Connaissez la différence et choisissez judicieusement les fonctionnalités avancées en ayant une connaissance complète d'au moins une analyse rapide des coûts/avantages.

Dans un petit environnement intégré, vous serez directement lié à un noyau en temps réel ou exécuté directement sur le matériel. Dans tous les cas, vous devrez vous assurer que votre code de démarrage d'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 de l'éditeur de liens, mais comme il est courant d'avoir un contrôle direct sur la source du 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 qui avait les initialiseurs C++ présents mais commentés. Si je l'avais utilisé directement de la boîte, j'aurais été mystifié par des objets globaux dont les constructeurs n'avaient jamais couru du tout.

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

64
RBerteig

Non. Toutes les fonctionnalités du langage C++ susceptibles de provoquer 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++ intégrés (je me souviens avoir lu des colonnes de développeurs intégrés utilisant C++ dans l'ancien Journal des utilisateurs C/C++), et je ne peux pas imaginer qu'ils seraient très vocaux si le choix était si mauvais.

25
Harper Shelby

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 d'Embedded C++ dans les réponses. La norme n'est pas à 100% à mon goût, mais c'est une bonne référence pour décider quelles parties du C++ vous pourriez abandonner.

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

Votre ami est la carte de l'éditeur de liens, cependant: 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 d'utilisation de la mémoire dynamique s'appliquent: dans un environnement aussi restreint que celui que vous mentionnez, vous pouvez ne pas utiliser du tout d'allocations dynamiques. Parfois, vous pouvez vous en tirer avec des pools de mémoire pour de petites allocations dynamiques, ou une allocation "basée sur des trames" où vous pré-allouez un bloc et jetez le tout plus tard.

20
leander

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

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

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

En tant qu'ingénieur du micrologiciel/système intégré, je peux vous expliquer pourquoi C est toujours le choix n ° 1 par rapport à C++ et oui, je parle couramment les deux.

1) Certaines cibles sur lesquelles nous développons ont 64 Ko de RAM pour le code et les données, vous devez donc vous assurer que chaque octet compte, et oui, j'ai traité l'optimisation du code pour économiser 4 octets) cela m'a coûté 2 heures, et c'est en 2008.

2) Chaque fonction de bibliothèque C est examinée avant de les laisser dans le code final, en raison de la limitation de taille, nous préférons donc que les gens n'utilisent pas diviser (pas de diviseur matériel, donc une grande bibliothèque est nécessaire), malloc (parce que nous n'avons pas de tas , toute la mémoire est allouée à partir du tampon de données dans un bloc de 512 octets et doit être révisée par du code), ou toute autre pratique orientée objet qui entraîne une forte pénalité. 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 parfois vous devez échanger des choses avec un autre ensemble de code. Si vous appelez une fonction de bibliothèque, la fonction de bibliothèque doit être résidente. Si vous ne l'utilisez que dans une fonction de superposition, vous perdez beaucoup d'espace en vous appuyant sur trop de méthodes orientées objet. Donc, n'assumez aucune fonction de bibliothèque C, et encore moins que C++ soit accepté.

4) La coulée et même l'empaquetage (où la structure de données non alignée traverse la limite de Word) sont nécessaires en raison de la 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 inplicitement, alors pourquoi l'objet l'oriente-t-il trop?

5) Scénario le plus défavorable: l'élimination de certaines des méthodes orientées objet forcera les développeurs à réfléchir avant d'utiliser des ressources qui peuvent exploser (c.-à-d. Allouer 512 octets sur une pile plutôt qu'à partir d'un tampon de données), et éviter certains des scénarios les plus défavorables potentiels qui ne sont pas testés ni éliminent le chemin de code entier tous ensemble.

6) Nous utilisons beaucoup d'abstraction pour garder le matériel du logiciel et rendre le code aussi portable que possible et convivial pour la simulation. L'accès matériel doit être encapsulé dans une macro ou une fonction en ligne qui sont compilées conditionnellement entre différentes plates-formes, le type de données doit être converti en taille octet plutôt que spécifique à la cible, l'utilisation directe du pointeur n'est pas autorisée (car certaines plates-formes supposent que les E/S mappées en mémoire sont les comme la mémoire de données), etc.

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

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

-un gars de firmware de SanDisk.

14
Shing Wong

Ma préférence personnelle est C car:

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

Pourquoi les gens disent ça? Vous ne savez pas savez ce que fait chaque ligne de C à moins que vous ne vérifiiez la sortie asm. Il en va de même pour C++.

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

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

Il 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 massivement de:

  • Les tailles de a, b et c.
  • si ces pointeurs sont stockés sur la pile ou sont globaux
  • si i, j et k sont sur la pile ou sont 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 tout aussi mauvais l'un que l'autre, à moins que vous n'examiniez toujours la sortie asm, auquel cas ils sont tout aussi bons les uns que les autres.

Hugo

10
Rocketmagnet

J'ai entendu dire que certaines personnes préfèrent C pour le travail intégré, car il est plus simple et donc plus facile de prédire le code réel qui sera généré.

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

8
user21714

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 voulez éviter les frais généraux de VMT, n'utilisez pas de méthodes virtuelles et de polymorphisme.

Cependant, C++ peut fournir des idiomes très utiles sans surcharge. Un de mes favoris est RAII. Les cours ne sont pas nécessairement chers en termes de mémoire ou de performances ...

7

J'ai écrit du code pour paltform intégré ARM7 sur IAR Workbench. Je recommande fortement de s'appuyer sur des modèles pour effectuer une optimisation au moment de la compilation et une prédiction de chemin. Évitez les lancers dynamiques comme la peste. Utilisez des traits/politiques à votre avantage, comme prescrit dans le livre d'Andrei Alexandrescu, Design C++ moderne .

Je sais, cela peut être difficile à apprendre, mais je suis également sûr que votre produit bénéficiera de cette approche.

6
GregC

Pour un système limité à 4K de RAM, j'utiliserais C, pas C++, juste pour que vous soyez sûr de voir tout ce qui se passe. Le problème avec C++, c'est qu'il est très facile d'utiliser beaucoup plus de ressources (à la fois CPU et mémoire) qu'il n'y paraît en regardant 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., etc.), mais vous passerez autant de temps à vous assurer que votre utilisation de C++ ne vous échappe pas comme vous le feriez pour l'équivalent en C .

5
Michael Kohne

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

5
shoosh

L'esprit humain traite de la complexité en évaluant autant que possible, puis en décidant de ce qui est important de se concentrer sur, et en rejetant ou en dépréciant le reste. C'est tout le fondement de la marque dans le marketing, et en grande partie, les icônes.

Pour lutter contre cette tendance, je préfère le C au C++, car cela vous oblige à penser à votre code et à la façon dont il interagit avec le matériel de plus près - sans relâche.

D'après ma longue expérience, je crois que C vous oblige à trouver de meilleures solutions aux problèmes, en partie, en vous éloignant de votre chemin et en ne vous obligeant pas à perdre beaucoup de temps à satisfaire une contrainte que certains auteurs-compilateurs pensaient être une bonne idée. , ou comprendre ce qui se passe "sous les couvertures".

Dans cette veine, les langages de bas niveau comme C vous font consacrer beaucoup de temps au matériel et à la construction de bons ensembles de structure de données/algorithmes, tandis que les langages de haut niveau vous font passer beaucoup de temps à vous gratter la tête en vous demandant ce qui se passe là-dedans et pourquoi vous ne pouvez pas faire quelque chose de parfaitement raisonnable dans votre contexte et votre environnement spécifiques. Battre votre compilateur en soumission (le typage fort est le pire contrevenant) n'est PAS une utilisation productive du temps.

J'adapte probablement bien 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, contrôle parfaitement. C vous donne beaucoup plus de contrôle que C++.

4
user1899861

Personnellement, avec 4 Ko de mémoire, je dirais que vous n'obtenez pas beaucoup plus de kilométrage du C++, alors choisissez simplement celui qui semble la meilleure combinaison compilateur/runtime pour le travail, car le langage n'aura probablement pas beaucoup d'importance.

Notez que ce n'est pas tout de même une question de langue de toute façon, car la bibliothèque est également importante. Souvent, les bibliothèques C ont une taille minimale légèrement plus petite, mais je pourrais imaginer qu'une bibliothèque C++ destinée au développement intégré est réduite, alors assurez-vous de tester.

3

Certains disent que les compilateurs C peuvent générer du code beaucoup plus efficace car ils n'ont 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.

2
Yishai

Voyez-vous une raison de rester avec C89 lors du développement pour du matériel très limité (4 Ko de RAM)?

Personnellement, en ce qui concerne les applications embarquées (quand je dis embarqué, je ne veux pas dire winCE, iPhone, etc. les appareils embarqués gonflés aujourd'hui). Je veux dire des appareils à ressources limitées. Je préfère le C, même si j'ai aussi beaucoup travaillé avec C++.

Par exemple, le périphérique dont vous parlez a 4kb de RAM, enfin juste pour cette raison, je ne considérerais pas le C++. Bien sûr, vous pouvez concevoir quelque chose de petit en utilisant C++ et limiter votre utilisation dans votre application comme l'ont suggéré d'autres articles, mais C++ "pourrait" potentiellement finir par compliquer/gonfler votre application sous les couvertures.

Allez-vous établir un lien statique? Vous voudrez peut-être comparer une application factice statique en utilisant c ++ vs c. Cela peut vous amener à considérer plutôt C. D'un autre côté, si vous êtes en mesure de créer une application C++ en fonction de vos besoins en mémoire, allez-y.

À mon humble avis, en général, dans les applications embarquées, j'aime savoir tout ce qui se passe. Qui utilise les ressources mémoire/système, combien et pourquoi? Quand les libèrent-ils?

Lors du développement pour une cible avec X quantité de ressources, CPU, mémoire, etc. J'essaie de rester sur le côté inférieur de l'utilisation de ces ressources, car vous ne savez jamais quelles seront les futures exigences, ce qui vous permettra d'ajouter plus de code au projet qui était "supposé" être une simple petite application mais finit par devenir beaucoup plus gros.

2
Steve Lazaridis

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 l'appareil 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 C++ (même si beaucoup se plaignent tout le temps qu'ils l'utilisent) ... mais je n'ai pas trouvé l'inverse vrai (d'après mon expérience).

Sur un projet sur lequel nous travaillons (qui implique un noyau au sol), la plupart des choses se font en C, mais une petite pile réseau a été implémentée en C++, car il était juste plus facile et moins problématique d'implémenter un réseau en C++.

Le résultat final est que l'appareil fonctionnera et passera les tests d'acceptation ou ne le fera pas. Si vous pouvez implémenter foo dans la pile xx et les contraintes de tas yy en utilisant le langage z, allez-y, utilisez ce qui vous rend plus productif.

Ma préférence personnelle est C car:

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

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

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

2
Tim Post

C gagne sur la portabilité - car il est moins ambigu dans les spécifications de langue; offrant ainsi une portabilité et une flexibilité bien meilleures 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.

2
Oliver

Combien de ROM/FLASH avez-vous?

4 Ko de RAM peut encore signifier qu'il y a des centaines de kilo-octets de FLASH pour stocker le code réel et les données statiques. RAM sur cette taille a tendance à être destiné uniquement à variables, et si vous êtes prudent avec celles-ci, vous pouvez adapter un assez grand programme en termes de lignes de code en mémoire.

Cependant, C++ a tendance à rendre plus difficile le placement de code et de données dans FLASH, en raison des règles de construction au moment de l'exécution des objets. En C, une structure constante peut facilement être placée dans la mémoire FLASH et accessible en tant qu'objet de constante matérielle. En C++, un objet constant nécessiterait que le compilateur évalue le constructeur au moment de la compilation, ce qui, je pense, est toujours au-delà de ce qu'un compilateur C++ peut faire (théoriquement, vous pourriez le faire, mais c'est très très difficile à faire dans la pratique) .

Donc, dans un environnement "petit RAM", "grand FLASH", j'irais avec C n'importe quand. Notez qu'un bon choix intermédiaire i C99 qui a la plupart des fonctionnalités Nice C++ pour le code non basé sur une classe.

2
jakobengblom2

La seule raison de préférer C IMHO serait que le compilateur C++ pour votre plate-forme ne soit pas en bon état (buggy, mauvaise optimisation, etc.).

1

Je veux juste dire qu'il n'y a pas de système avec des ressources "ILLIMITÉES". Tout dans ce monde est limité et CHAQUE application devrait considérer l'utilisation des ressources, que ce soit son ASM, C, Java ou JavaScript. Les mannequins qui allouent quelques Mbs "juste pour être sûr" font de l'iPhone 7 , Pixel et autres appareils extrêmement luggy. Que vous ayez 4 Ko ou 40 Go.

Mais d'un autre côté pour s'opposer au gaspillage des ressources - c'est un temps qui prend pour sauver ces ressources. Si cela prend 1 semaine supplémentaire pour écrire une chose simple en C pour é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 latérale - même la puissance de votre prise n'est pas illimitée. Essayez de rechercher d'où cela vient et vous verrez surtout que c'est de brûler quelque chose. La loi de l'énergie et du matériau est toujours valable: aucun matériau ou énergie n'apparaît ou disparaît mais se transforme plutôt.

1
Alex Paniutin

Vous avez en ligne dans C99. Peut-être que vous aimez les ctors, mais la tâche de bien faire les dtors peut être compliquée. Si la seule raison restante de ne pas utiliser C est les espaces de noms, je m'en tiendrai vraiment à C89. En effet, vous souhaiterez peut-être le porter sur une plate-forme intégrée légèrement différente. Vous pouvez ensuite commencer à écrire en C++ sur ce même code. Mais méfiez-vous de ce qui suit, où C++ n'est PAS un surensemble de C. Je sais que vous avez dit que vous avez un compilateur C89, mais fait quand même cette comparaison C++ avec C99, car le premier élément par exemple est vrai pour tout C depuis K&R.

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 des membres de tableau de variables VAM. Exemple: struct {int b; int m [];}.

1
hept

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 être coûteuses en termes de temps processeur et d'empreinte mémoire.

Notez que certaines choses comme le polymorphisme peuvent être très précieuses - ce sont essentiellement des pointeurs de fonction. Si vous trouvez que vous en avez besoin, utilisez-les judicieusement.

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

1
Foredecker

Le livre C++ for Game Programmers contient des informations relatives au moment où la taille du code augmentera en fonction des fonctionnalités de C++.

1
zooropa

Pour les problèmes d'allocation de mémoire, je peux recommander d'utiliser Quantum Platform et son approche de machine d'état, car il alloue tout ce dont vous avez besoin au moment de l'initialisation. Il aide également à atténuer les problèmes de conflits.

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

0
GregC

Réponse différente à un aspect différent de la question:

"malloc"

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

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

0
jakobengblom2

Cela dépend du compilateur.

Tous les compilateurs intégrés n'implémentent pas tout C++, et même s'ils le font, ils pourraient ne pas être 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 étant donné un compilateur bon, non, il n'y a aucune raison de ne pas utiliser C++.

0
jalf

Je viens de trouver un exemple comment utiliser ISO C++ pour le développement embarqué, qui pourrait être intéressant pour quelqu'un qui prend la décision chaque fois que vous utilisez C++ ou C.

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

Pour voir comment ISO C++ peut être utilisé pour une programmation sérieuse de systèmes embarqués, voir Normes de codage C++ pour véhicules aériens JSF .

0
Piotr Czapla

Il existe un certain nombre de fabricants de contrôleurs différents dans le monde et lorsque vous examinez leurs conceptions et les jeux d'instructions qui doivent être utilisés pour la configuration, vous pouvez vous retrouver dans de nombreux problèmes. Le principal inconvénient du langage d'assemblage est qu'il dépend de la machine/de l'architecture. C'est vraiment énorme demander à un développeur de suivre par cœur toutes les instructions qui y sont énoncées pour effectuer le codage pour différents contrôleurs. C'est pourquoi C est devenu plus populaire dans le développement embarqué parce que C est suffisamment élevé pour abstraire les algorithmes et les structures de données des détails dépendants du matériel, ce qui rend le code source portable sur une grande variété de matériel cible, de langage indépendant de l'architecture et très facile à convertir et maintenir le code. Mais nous voyons certains langages de haut niveau (orientés objet) comme C, C++, Python, Java etc.) évoluer suffisamment pour les placer sous le radar du développement de systèmes embarqués.

0