C++: mity i fakty

W latach 90. rozpowszechniła się w kręgach zainteresowanych tematyką opinia, że język C++ nie nadaje się do tego, żeby pisać w nim programy dla mikrokontrolerów jednoukładowych. W przypadku małych systemów 8- i 16-bitowych, dominujących w tamtym okresie, jest to zapewne prawda. Ale dziś, w dobie tanich mikroprocesorów 32-bitowych o wielkiej (w porównaniu do tych z poprzednich dekad) mocy przetwarzania i znacznych zasobach, można sobie zadać pytanie, na ile ta niezbyt pochlebna dla C++ opinia ma nadal pokrycie w faktach, a na ile jest utrzymującym się siłą inercji mitem.

Dodaj do ulubionych źródeł w Google
Posłuchaj
00:00
Spis treści

Kwestia pamięci ROM

Linkery przeznaczone do systemów jednoukładowych pozwalają na umieszczanie stałych w pamięci ROM. W języku C wszystkie dane, co do których jest pewność, że są stałe, można w związku z tym zainicjować podczas kompilacji, co pozwala na umieszczenie ich w ROM-ie.

W C++ można zrobić to samo, ale niezbyt to pasuje do obiektowego stylu programowania. W dobrze napisanym programie w C++ większość danych jest zawarta w obiektach, obiekty należą do klas, a klasy mają konstruktory. Obiekt może być określony jako const, a obiekt określony jako const static i mający konstruktor musi zostać umieszczony w pamięci RAM, gdyż w przeciwnym wypadku konstruktor nie będzie go mógł zainicjować.

A zatem, gdzie w języku C obiekt const static znajdzie się w ROM-ie, który jest tani i jest go dużo, tam w C++ jego najbardziej naturalny odpowiednik musi rezydować w drogim i niezbyt obszernym RAM-ie. Inicjowanie wykonuje kod znajdujący się w pamięci ROM i wywołujący po kolei wszystkie konstruktory z parametrami odpowiednimi dla poszczególnych deklaracji. Ten kod zajmuje więcej miejsca niż mogłyby go zająć dane statycznie inicjujące dane obiekty (jak to jest w C).

Jeśli chcemy dane umieścić w pamięci ROM, trzeba poświęcić nieco uwagi konstrukcji klas tak, żeby odpowiadające im obiekty mogły się tam znaleźć. Przede wszystkim, obiekt musi być statycznie zainicjowany, tak jak struktura w języku C. Mimo że łatwo jest to osiągnąć przez zadeklarowanie go jako struktury (bez metod), da się jednak i tu użyć nieco bardziej obiektowych metod programowania.

Statyczne inicjowanie obiektów jest dozwolone pod następującymi warunkami:

  • klasa nie może być klasą pochodną,
  • w klasie nie może być konstruktora,
  • w klasie nie może być metod wirtualnych,
  • klasa nie może zawierać elementów oznaczonych jako private lub protected,
  • wszelkie klasy w niej zawarte muszą spełniać te same kryteria,
  • wszystkie metody muszą zostać zadeklarowane jako const.

Mimo że to rozwiązuje bezpośredni problem umieszczenia obiektu w pamięci ROM i rozszerza zwykłą strukturę C o metody, dalekie jest jednak od ideału programowania obiektowego, który stanowi klasa łatwa do prawidłowego, a trudna do nieprawidłowego użycia. Nieuważny programista może, na przykład, zadeklarować niezainicjowaną i nieconst instancję tej klasy albo uzyskać dostęp do jej struktur wewnętrznych z pominięciem zdefiniowanych metod, a jej projektant nie jest w stanie temu zapobiec.

Rozwiązanie tego problemu wymaga czegoś więcej. Tym czymś jest zagnieżdżanie klas: w C++ można deklarować jedne klasy wewnątrz drugich. Można zatem taką klasę, zdefiniowaną jak powyżej (gdzie, jak powiedziano, zachodzi ryzyko nieprawidłowego użycia) umieścić w prywatnej części innej klasy. A instancje const static tej klasy można uczynić elementami private static klasy-opakowania. Ta zewnętrzna klasa nie podlega restrykcjom nałożonym na to, co chcemy ulokować w ROM-ie, możemy więc sobie w niej zdefiniować interfejs dostępu do naszych danych statycznych.

Nie ma tu miejsca na przykładowe listingi - są nieco zbyt obszerne - poprzestaniemy więc na ogólnym wskazaniu, że w danym wypadku potrzebna jest bardzo przemyślana konstrukcja klas. A z drugiej strony, jest prawdą, że nieprzemyślane użycie tego czy tamtego w C++ może prowadzić do niespodziewanego i niepożądanego rozrostu kodu wynikowego, ale tak samo jest w języku C. Rozważmy przykład takiej, wyglądającej zupełnie niewinnie, deklaracji:

int var = 1.0;

Wartość po prawej stronie jest liczbą zmiennoprzecinkową. Co za tym idzie, kompilator co prawda nie musi, ale może wstawić do kodu odwołanie do biblioteki obsługującej obliczenia zmiennoprzecinkowe w celu dokonania konwersji typu. Jeszcze gorszy skutek może pociągnąć za sobą nieuważne skorzystanie w programie z funkcji printf() - nie każdy się tego spodziewa, ale jest ona dość rozbudowana. Ale takie pomyłki raczej nie skłonią nikogo do twierdzenia, że język C nie nadaje się do oprogramowywania systemów jednoukładowych. Podobnie sprawa wygląda z nieprzemyślanym użyciem pewnych konstrukcji C++.

Biblioteki

Jedną z korzyści, jakie przynosi stosowanie C++, jest możliwość użycia bibliotek klas. Język zorientowany obiektowo sprawia, że biblioteki klas są łatwiejsze w użyciu niż ich odpowiedniki strukturalne (w języku C), trudniej jest także ich nadużywać. Ale tak samo jak w przypadku bibliotek języka C niektóre z nich powodują znaczny rozrost programu, a to nawet mimo (o czym też już wspominano powyżej) że współczesne linkery potrafią wyłuskać z bibliotek i dołączyć do programu tylko te metody, którymi program rzeczywiście się posługuje.

W każdym wypadku przed podjęciem decyzji o użyciu konkretnej biblioteki, należy zbadać, jaki to będzie miało wpływ na wielkość gotowej aplikacji. Dotyczy to zresztą nie tylko bardzo wymyślnych, specjalistycznych bibliotek - na początek można zbadać, jakiej wielkości w danym środowisku będzie jakiś trywialny program w rodzaju "Hello world": może się on okazać niespodziewanie duży w porównaniu z odpowiednikiem w C.

Nowsze definicje języka C++, tj. C++11 i C++14, wprowadziły do niego parę udogodnień, które, jak te powyżej opisane, ograniczają się częściowo tylko do składni i tym samym nie mają wpływu na docelową wielkość i wydajność kodu, inne natomiast jak najbardziej, zwłaszcza jeśli dojdzie do ich lekkomyślnego nadużycia.

Nie ma tu miejsca na ich szczegółowe omawianie. W ramach ogólnej konkluzji można stwierdzić, że negatywne opinie na temat przydatności C++ dla systemów jednoukładowych są mocno przesadzone: do złych skutków prowadzi nie tyle samo w sobie użycie tego języka, ile nieuważne korzystanie z jego konstrukcji i uleganie przez programistów nawykom, których nabrali podczas pracy na większych komputerach. Pisząc program w C++, zwłaszcza nigdy nie należy zapominać o tym, że maszyna docelowa dysponuje ograniczonymi zasobami, a w razie wątpliwości trzeba zawsze sprawdzać, jak użycie danej konstrukcji C++ przekłada się na wielkość i wydajność kodu wynikowego.

Konrad Kokoszkiewicz

Chcesz częściej widzieć nasze artykuły w Google? Dodaj ElektronikaB2B do ulubionych źródeł
Spis treści
Powiązane treści
PRQA wprowadza narzędzie do analizy statycznej QA·C++ w nowej wersji V3.2
Zobacz więcej w kategorii: Technika
Produkcja elektroniki
Szablon SMT a jakość nadruku pasty lutowniczej
Elektromechanika
Dobór obudowy do urządzenia elektronicznego – materiały, szczelność i możliwości modyfikacji
Produkcja elektroniki
Wady lutowania na fali - jak ograniczyć mostkowanie i niedobory lutu?
Komunikacja
Lokalizacja UWB w budynkach – od czego zależy dokładność pomiarów?
Optoelektronika
Sterowanie oświetleniem LED - jak ograniczyć migotanie i zapewnić precyzyjną regulację jasności?
Produkcja elektroniki
Pustki w połączeniach BGA – jak interpretować normy IPC i wyniki inspekcji rentgenowskiej?
Zobacz więcej z tagiem: Artykuły
Magazyn
Październik 2026
Magazyn
Wrzesień 2026
Magazyn
Sierpień 2026

Zobaczyć obiekt oczami radaru, czyli dlaczego potrzebujemy laboratorium do pomiarów RCS?

Radar postrzega świat inaczej niż człowiek. Zamiast obrazu tworzonego przez światło widzialne rejestruje echo wysłanej fali elektromagnetycznej. Na odpowiedź radarową obiektu wpływają nie tylko jego rozmiary, lecz także kształt, zastosowane materiały, częstotliwość oraz kierunek obserwacji. Dlatego dwa przedmioty o podobnych wymiarach mogą być dla radaru widoczne zupełnie inaczej. Jak zatem sprawdzić, co radar rzeczywiście "widzi"? Służą temu pomiary RCS, prowadzone między innymi w specjalistycznych laboratoriach, które zapewniają kontrolowane i powtarzalne warunki oraz umożliwiają uzyskanie dokładności wymaganej w danym zastosowaniu.
Zapytania ofertowe
Unikalny branżowy system komunikacji B2B Znajdź produkty i usługi, których potrzebujesz Katalog ponad 7000 firm i 60 tys. produktów