avr-gcc: Czy można wywołać ...

W C++ to proste do zrobienia, jeśli się zna pare sztuczek z szablonami. Natomiast w C nie da się czegoś takiego uzyskać. No cóż, ale jeśli ktoś sobie sam nakłada kaganiec, a później narzeka, że nie może gryźć, to już jego problem... :-)

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski
Loading thread data ...

No ładnie :/ Chyba musze jednak poćwiczyc c++ na AVRach ... skoro tak namiawiasz strasznie :)

Reply to
Sebastian Bialy

Szczerze mówiąc to nie widzę większej potrzeby intensywnego używania metod wirtualnych na mikrokontrolerach. A jesli jednak ich trzeba, to też dużo nie kosztują: jeden dodatkowy wskaźnik w klasie, a w kodzie to jedna dereferencja i jeden skok pośredni. Problemy ze złożonością pojawiają się, gdy korzysta się z metod wirtualnych w hierarchii klas z dziedziczeniem wielobazowym, ale tego rzadko kiedy potrzeba na "prawdziwych" komputerach.

Właśnie o to porządkowanie chodzi, żebyś się w większym projekcie nie zabił zaplątując we własne spodnie. ;-)

A dlaczego na mikrokontrolerze masz ich nie mieć? Są za darmo. Oprócz tego masz idiom "placement new", na mikrokontrolerach również bardzo przydatny i zupełnie darmowy.

Wyjątki są za drogie w obsłudze, maluchy mają za mało RAMu na stos. Każdy znany mi kompilator pozwala wyłączyć ich obsługę.

A co Ty chcesz inkludować na mikrokontrolerze, gdzie wszystko jest wysoce niestandardowe? :-)

Jest bardzo dobrym pomysłem, tylko przed pisaniem trzeba skończyć z wiarą w mity. ;-)

Szablony w Javie działają na zupełne innej zasadzie niż w C++ -- tam nie tylko składnia, ale cała filozofia za nimi stojąca jest zupełnie inna.

Oprócz wspomnianych już szablonów w C++ masz dziedziczenie wielobazowe, dziedziczenie wirtualne, zupełnie inne zasady wiązania nazwy obiektu z obiektem (m.in. lookup Koeniga -- to chyba jedyny język, który implementuję ten wynalazek) i przestrzenie nazw. W C++ się pisze zupełnie inaczej niż w Javie, no chyba, że ktoś zna C++ na poziomie "C z klasami" i w takim zakresie go używa -- wówczas zgoda, ale czuję się w obowiązku donieść, że to zaledwie ułamek dostępnych możliwości i daje się zapisać w tym języku takie cuda, że mało kto zdaje sobie sprawę, że to w ogóle możliwe. Ot, choćby takie sprawdzanie w czasie kompilacji hierarchii dziedziczenia za pomocą bardzo pokrętnie skonstruowanego szablonu i niecodziennego wykorzystania operatora sizeof. Majstersztyk.

Jeśli oferowane przez nie możliwości przekładają się w łatwy sposób na kod wynikowy, to oczywiście, że tak. W C++ większość nowych możliwości jest dostępna zupełnie za darmo.

To jest nieosiągalne nawet w C, potrzeba wstawki asemblerowej. A to się robi równie łatwo w C++.

C++ nie różni się pod tym względem od C.

Do tego też trzeba wstawki asemblerowej.

Będzie ich tyle samo w C++, co w C.

Jest, C++.

A niby czemu miałoby się nie dać, i to nawet wydajnie? Znowu jakieś mity. ;-)

Nie przesadzam, w różnych miejscach takie programy są stosowane. W jednym program się zawiesi i będzie odtwarzał tę samą piosenkę, w innym bank straci kilkadziesiąt tysięcy dolarów, a w jeszcze innym trzeba się będzie zastanawiać, co zrobić z denatem...

Są kłopoty, czasami w postaci ofiar śmiertelnych i kalek.

Więc je wywal i przejdź na jego następcę, w czym -- oprócz mitów -- widzisz problem?

Nie, nie równie dobrze. W jednych lepiej, w innych gorzej i dlatego jest ich tyle.

A jak definiujesz kryterium optymalności i w jaki sposób chcesz sprawdzać jego spełnialność? Chyba nadużywasz tego słowa. ;-)

Szkoda.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

J.F. napisał(a):

to może coś takiego?

#define F_CPU 10000000L #define CYCLES F_CPU/100

#if CYCLES > 65535 #warning "unsigned long" unsigned long cnt; #else #warning "unsigned short" unsigned short cnt; #endif

int main(void) { return 0; }

taki kod zadeklaruje unsigned long, bo cykli mamy 100000. jeśli zmienisz stałą F_CPU na 5000000, zadeklaruje unsigned short. o to chodziło?

preprocesor gcc nie poradzi sobie ze stałymi zmiennnoprzecinkowymi, ale większość rzeczy można policzyć na stałoprzecinkowych przy odpowiednim przesunięciu wartości.

kod wyżej radzi sobie ze stałymi.

zaznaczam, że cały czas mowa o gcc. inne kompilatory faktycznie mogą ignorować obliczenia w preprocesorze i zrzucać je na kompilator, ale nie wiem czy to rozszerzenie gcc czy nowość w C99.

w.

Reply to
Wojtek Kaniewski

Na przykład najmniejszą wspólną wielokrotność? :-)

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski
[Soko nie chcesz EOT ...]

Widzisz, mamy zupełnie inne podejście do programowania obiektowego - w moim przypadku, kiedy już decyduje się na C++ to zycze sobie PEŁNEGO c++ włacznie z STL, metodami wirtualnymi, wyjątkami i cała masą innych fajnych rzeczy. Jesli natomiast za pomocą kompilatora C++ składam proste programy to nie uważam tego za pisanie w C++ a jedyne za używanie kompilatora C++.

Chyba się tutaj nie zgodzimy, bo to po prostu nasze indywidualne zdania na temat "definicji C++".

Owszem, dlatego tak bardzo cenie C++, jednak z drugiej strony: co to znaczy większy projekt ? Jesteś ograniczony dostępnym ram/rom w uC i w zasadzie kazdy większy projekt na taki uC da się objąć i zapanowac nad nim. Co innego pisanie duzych aplikacji na peceta. Po prostu ilośc kodu jaki można wrzucić do przeciętnego AVRa nie jest moim zdaniem "dużym" projektem. Fakt - C++ ładnie pozwala odciązyć programistę od myślenia o róznych pierdołach, ale z drugiej strony pisząc na 90S2313 w zasadzie jesteś w stanie zapamiętać wszystkie zmienne jakie używasz i w jakim pliku ;)

To nie znaczy że nie należy pisać w C++ na uC - tylko że imho argument komplikacji jest tu troche nie w tej skali.

Zwróć uwagę na masę kłopotów, które się "robią same" takie jak tworzenie tymczasowych obiektów przy arytmetyce przeciążonych operatorów (które tak lubie stosować :), konstruktory kopiujące (często niepotrzebne) i tym podobne rzeczy, których IMHO kompilator raczej nie zoptymalizuje (może się mylę ?). Przy <1kB pamięci RAM może się okazać, że stworzenie tymczasowego obiektu w RAM jest niewykonalne. Można powiedziec, że o ile C++ ułatwia pewne rzeczy składniowo, to czasami potrafi wygenerować kod nadmiarowy wynikający z samej definicji obiektu przez programistę.

Szkoda :) Czyli "-" dla C++ ? :)

Jesli poczytasz helpa do WinAVR to dowiesz się, że w ostatniej wersji jaką dałem radę ściągnąć częśc plików jest "not C++ safe" a konkretnie nie mają 'extern "C"'. Czyli raczej nie da się korzystać swobodnie (choć mam nadzieje, to nie będzie wiele dla twórców poprawić).

I ostro zacisnąć pasa w tym C++ :)

Oj, wiadomo że kazdy język ma spore róznice, ale chodzi o to, że większośc programistów Java jest w stanie pisać w C++ i na odwrót. To są języki _BARDZO_ podobne, że wręcz wspomne o samej składni, która jest prawie identyczna. A to że są szczegóły rózne (brak destruktorów w Javie mnie dobił, choć rozumiem dlaczego ich nie ma) to wiadomo. Co do filozofi to nie wiem czy mówisz o całym jezyku czy tylko o jego częsci, ale dla mnie nie było zadnych kłopotów w pare dni przegryźć się przez róznice Java-C++ i pisac programy w Javie, więc filozofia nie jest aż taka rózna. Acz daleko mi do miana programisty javy.

Jakie ma znaczenie majsteresztyk, skoro można badać typy/rzutować z użyciem mechanizmów w C++ ? Tzn jestem wrogiem sztuczek programistycznych, bo to zamiast ułatwiać zycie - zaciemnia tak, że komuś rękę urwie kiedyś :P

Co do przestrzeni nazw - ile to programów w C wyrosło bez tego "bajeru" i jakoś nikt specjelnie nie płakał... Fajno ze jest ale można się było obejść bez. To troche tak, że brak "for" byłby bolesny, ale brak "namespace" jakoś nie spowodował zastoju C (dalej jajko linuxa w nim skrobią, choć istniało by wiele lepszych języków).

Hmmm ok. Zakładam, że teoretycznie masz rację. Jednak jestem przekonany że przeciętny dobry programista C++ na dużych pecetach wybije sobie zęby od razu o mały RAM/mały stos w uC. Pisanie na uC jednak rózni się od pisania na duże komputery. Dużo zależy od umiejśtności programisty, jednak jesli wykastrujemy C++ z STL, wyjątków i paru innych duperelek to okaże się, że w zasadzie pozostał C + troche "bajerów składniowych" typu szablony. To dla mnie nie C++ (ale to wyjasniłem, że to kwestia definicji).

Hmmm moment, nie chodzi mi o rejestry uC tylko o rejestry specjalne, z resztą chodziło mi o języki odległe od sprzętu a nie o C++ który oczywiście jest "lepszym C" choć zdaje sobie sprawę, że wiele osób mogło by mnie zamordować za to stwierdzenie :)

J/w.

Łomatko :) No dobra, C++ wykastrowany, robocza nazwa "1/2C++" może byc ? :)

Heh, no ja się nie podejmuje, chyba że dobrze zapłacisz :) A potrzebujesz FAT w BASCOMIE ? :P Cos mi się zdaje że BASCOM nie powstał do takich zastosowań (co nie zienia faktum że można).

Dziwnym trafem nie przeszkadzają te negatywne doświadczenia na całym swiecie stosować windowsa do obsługi szaf muzycznych (zaliczyłem już 4 sztuki wesoło zawieszone na niebieskim ekranie), bankomatów ze znakiem zachęty C:> na ekranie (przoduje tu PKO, 2 trafienia) tudzież informatorów turystycznych nie mogących znaleźć pliku "xxxx.dll" (chyba wszystkie jakie widziałem miały jakiś mankament typu "programista dał dupy"). Jakoś nikt się nie przejmuje stabilnoscią bankomatu, bo przeciętny klient jest mało znaczacy. Co do aparatury medycznej - mysle że zakładając odpowiedni poziom kontroli - kazdy jezyk nalezy gruntownie przetestowac, a im wyżej się wspinasz w łatwości programowania, tym mniej rzeczy zalezy od programisty a więcej od dostawcy bibliotek/kompilatora/etc. Ciekawe czy takie aplikacje dla .NET na ten przykład można stosować w medycynie ? W sumie ja bym nie zaufał tym gotowcom z MS.

Podobnie jak piszących w C++/BASCOMie/whatever, ale nie mam statystyk więc nie mam odwagi wyrokowac, czy więcej ...

We wszystkim o czym dyskutujemy, co praktycznie zawsze ma źródło w "małej ilości RAMu" co wymusza kastrację.

"Równie dobrze" w tym przypadku oznaczało, że można napisac każdy program w kazdym języku, ale:

Optymalnie: szybki kod, mało zajetości RAMu (w szczególności na pierdoły typu obiekty tymczasowe), zwarty kod. Każdemu przypisuje wage w zalezności od projektu i tak pisze, aby zoptymalizowac funkcję celu :P. W C/C++ mam pod kontrolą bardzo wiele elementów. W wyższych językach coraz mniej. Dlatego w przypadku uC raczej nie chce pisać w BASCOMie, bo mam mniejszy wpływ na generowany przez niego kod.

No dobra, ale się rozpisujemy, ja proponuje powoli kończyć, choć z przyjemnością sie dyskutuje.

Reply to
Sebastian Bialy

Piotr Wyderski napisał(a):

teraz to już szukasz dziury w całym (;

a na poważnie, to jak na podstawie wyniku czegoś w stylu boost::math::static_lcm<x,y> zadeklarować zmienną? czy może trzeba własne szablony tworzyć?

w.

Reply to
Wojtek Kaniewski

Nie, pokazuję tylko, że nie da się w ten sposób zapisać nawet najprostszej rekurencyjnej zależności, bo w preprocesorze rekursji nie ma. W obliczeniach za pomocą szablonów jest.

Tj. jak wybrać typ zmiennej? Na przykład tak (rozwiązanie ogólne):

template <bool, typename T, typename F> struct select_type { typedef T type; }; template <typename T, typename F> struct select_type<false,T,F> { typedef F type; };

I użycie:

select_type<(2*2 == 4), char, double>::type zmienna;

Oczywiście warunek może być dowolnie bardziej skomplikowany, być wyznaczany przez zależność rekurencyjną itd. -- ogranicza fantazja.

Na podobnej zasadzie (tj. za pomocą częściowej specjalizacji szablonu) można sobie zrobić odpowiednik instrukcji case (zamiast if), jeśli komuś jest potrzebna -- tylko parametryzacja powinna wówczas korzystać z typu unsigned int, a nie bool.

Tak, ale -- jak widzisz -- bardzo proste i do tego uniwersalne. Ja sobie dziesiątki tego typu rzeczy zamknąłem we własną biblioteczkę i korzystam z niej od paru lat, od czasu do czasu dopisując do niej coś wartego uwagi.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

Piotr Wyderski napisał(a):

widzę, że pora zainwestować w jakąś sensowną książkę o C++. do tej pory miałem nieszczęście przeglądać takie, które skupiały się na klasach, a o szablonach wspominały po łebkach.

tak czy inaczej wielkie dzięki za wyjaśnienia.

w.

Reply to
Wojtek Kaniewski

Polecam Andrei Alexandrescu, "Modern C++ design".

formatting link
I zapiąć pasy, bo jazda będzie ostra.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

A czemu mam chcieć, dyskusja wygląda ciekawie. :-)

Nie, do programowaia w C++. O programowaniu obiektowym niewiele mówiliśmy, a poza tym C++ dość mało ma z nim wspólnego.

A jesli piszesz w C, to życzysz sobie pełnego zestawu funkcji matematycznych, funkcji wejścia-wyjścia oraz plików, mimo, że w danym systemie pojęcie pliku nie ma sensu?

Jaka komplikacja?

Przeciążone operatory arytmetyczne na AVR-ku?!

Zoptymalizuje, choć kiedyś miał kłopoty z NRVO i powstał taki tymczasowy idiom "operator(parametry) return nazwa_zmiennej { treść_operatora }"

-- ostatnio go wycofano.

Jasne, ale należy do tego dodać, że programista powinien był wiedzieć na czym polega działanie użytego mechanizmu i być świadom skutków ubocznych. Pierwsze przykazanie: mysleć. ;-)

A czy fakt, że karaluchy miewają problemy z opanowaniem chińskiego cos chińskiemu ujmuje? :-)

To żaden minus, po prostu nie ma miejsca na stos wyjątków. A jak nie ma stosu wyjątków, to nie ma i wyjątków.

no to nadaj im go hurtem, pisząc w swoim kodzie

extern "C" {

#include <stdio.h>

#include <stdlib.h>

#include <cośtam.h>

}

int main() { [...]

Tego Ci brakowało? :-)

Rezygnując z wyjątków to ostro? A co m.in. z nieporównywalnie bardziej potrzebnym programowaniem generycznym i dziedziczeniem, które żadnych nakładów nie wymaga?

Ano jest, wykorzystując jakieś 20% dostępnych możliwości. Reszty się przenieść nie da.

Tylko o Java generics -- działają na zupełnie innej zasadzie niż szablony znane z C++.

Generics weszły do Javy tak niedawno, że chyba nie ma o nich jeszcze wiele w żadnej książce. :-)

Cały czas mówię o tym, co da się osiągnąć w standardowym C++, a nie dzięki rozszerzeniom albo zewnętrznym narzędziom. Stąd wszystko jest "mechanizmem C++", więc niezupełnie rozumiem, o co Ci chodzi, ale przypuszczam, że o dynamic_cast<>. Jeśli tak, to wartość dynamic_cast jest obliczana w czasie działania programu, a nie jego kompilacji, więc się nie nadaje do większości ciekawych zastosowań, m.in. generowania optymalnej struktury programu dla danego zbioru parametrów (Twój wątek też nalezy do tego zbioru). Mozna chcieć otrzymać w C++ takie mechanizmy o dużym znaczeniu praktycznym:

  1. Optymalne przekazywanie parametrów do funkcji i metod. Niemodyfikowalne parametry można przekazywać w C++ przez stałą wartość albo przez referencję do obiektu stałego. Jeśli parametr jest "mały" (np. jakaś liczba naturalna), to najtaniej będzie przekazać go przez wartość. Gdy jest "duży" (obiekt klasy o wielu składowych niestatycznych itp.), to znacznie taniej wyjdzie przekazać referencję niż tworzyć jego tymczasową kopię w rekordzie aktywacji wywoływanej procedury. Bardzo małe obiekty klas (np. zawierające tylko jedno pole typu int) jednak lepiej przekazywać przez wartość, bo dostęp pośredni jest kosztowniejszy niż bezpośredni. Ponieważ z góry nie wiadomo, jaka metoda będzie optymalna w _konkretnym_ przypadku (bo zmieniamy docelowy procesor na większy, albo po prostu rozbudowaliśmy klasę o nowe pola, czy też pozbyliśmy się niepotrzebnych), chcielibyśmy mieć prosty w użyciu mechanizm, który pozwoli kompilatorowi wybrać optymalną dla danego parametru metodę przekazywania.

Czy da się to zrobić nie uciekając się do rozszerzeń albo nie edytując w pocie czoła wszystkich plików źródłowych po każdej zmianie definicji typów?

  1. Wymuszanie rozwijania pętli. Chcielibyśmy napisać klasę działającą na wektorch danych podanego typu, o podanej długości N. Chcemy mieć m.in. operację ich dodawania. Moglibyśmy napisać w pętli

for(k = 0; k < N; ++k) c[k] = a[k] + b[k];

ale gdy N jest małe, to stracimy znacznie więcej czasu na obsługę pętli niż na właściwe dodawanie. Moglibyśmy więc w takich przypadkach rozwinąć tę pętlę i dla N = 3 zastąpić ją

c[0] = a[0] + b[0]; c[1] = a[1] + b[1]; c[2] = a[2] + b[2];

Gdyby jednak N było duże, to takie rozwinięcie spowodowałoby gigantyczny wzrost objętości kodu, więc tu jednak lepsza byłaby pętla. Poza tym jesteśmy leniwi i nie chcemy na sztywno wkodowywać rozwinięć, bo może się nam zmienić maszyna albo po prostu więcej się dowiemy i nasza definicja tego, jakie N jest małe, a jakie duże może się zmienić. Chcielibyśmy móc tylko podać kompilatorowi w jednym miejscu to, co w chwili obecnej uważamy za małe i jakiego N potrzebujemy, a o wygenerowanie odpowiednich wariantów niech on się już zatroszczy sam -- w końcu lenistwo jest motorem postępu. My będziemy tylko pisać

wektor<4> a, b, c; c = a + b;

albo

wektor<1000> a, b, c; c = a + b;

a nasz kod niech sobie sam tak zmodyfikuje strukturę, by w pierwszym przypadku (N=4) w pełni się rozwinął, a drugi został policzony w pętli, bo akurat za małe uznajemy wszystko, co ma mniej niż 6 elementów. Da się coś takiego zrobić?

  1. Optymalny typ zakresowy. Do iterowania po różnych zakresach parametrów przydałoby się mieć typ range, któremu powiemy tylko, jakie wartości minimalne i maksymalne może przyjąć parametr, a kompilator niech dobierze mu odpowiedni typ. Jeśli ten typ będzie za duży, np. 64-bitowy, to się program będzie bardzo wolno wykonywał, a jeśli za mały, to nastąpi przepełnienie i program się popsuje. Dlatego typ iteratora ma być w sam raz i być dobierany automatycznie na podstawie podanego przez nas zakresu oraz na podstawie zakresów właściwych dla danej maszyny (np. int ma 16 bitów). Nas to nie obchodzi -- ma działać, i to działać optymalnie.

for(range<-10,150> k = -5; k < p; ++k) [...]

Da się to zrobić?

Sztuczek? Każdy z powyższych kodów będzie małym dziełem sztuki (o ile da się go napisać -- da się? :-)), a nie żadną sztuczką... :-)

Zaciemnia? Trudno sobie wyobrazić czytelniejsze deklaracje niż, odpowiednio:

fn(best_mode<int>::type k); wektor<457> w; range<0, 2779> i;

Nieakceptowalnie wiele.

Zrobisz konflikt deklaracji, to będziesz miał zastój. ;-)

Nie wiem, nie prowadziłem na ten temat badań statystycznych. Ja sobie radzę równie dobrze w obu tych środowiskach, dlatego pozwalam sobie klasyfikować wiele Twoich uwag jako mity -- nie próbowałeś czegoś zrobić, a z uporem bronisz przekonań, które nie mają oparcia w faktach. Spróbuj, chętnie podyskutuję, ale z rzeczywistymi doświadczeniami, a nie z uprzedzeniami. ;-)

Jak zawsze.

Heh, Sebastianie, jeśli uważasz szablony za bajerek składniowy, to z pewnością nigdy z nich nie korzystałeś w bardziej zaawansowany sposób. Wyrzuć z C++ cokolwiek sobie życzysz, ale szablony mi zostaw, bo to głównie z ich powodu używam tego języka. :-)

Procesora? No to tym bardziej się do nich nie dostaniesz z poziomu C, tylko wstawka asemblerowa (albo rozszerzenie, jak sfr w Keilu) będzie dostatecznie silna.

Ale _z czego_ wykastrowany, z wyjątków? To jest dla Ciebie połowa tego języka? :-)

Pewnie i nie powstał, ale jeśli ktoś mi zaproponuje dostatecznie wysoki stosik zachęcaczy, to i w kodzie binarnym mu to napiszę. :-)

Owszem, świat schodzi na psy... ;-)

Przecież ani szablony, ani dziedziczenie, ani przestrzenie nazw Ci nawet bitu tego RAMu nie zjedzą... :-)

Ciekawe, czy ktoś tu dotarł? :-)

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

Racja, przejęzyczenie.

Oczywiście ;) :P Myslisz że nie próbowałem liczyć na atmedze sinusów ? A i owszem, kiedys się przydazyło, co gorsza szykuje mi sie projekt w którym jest _naprawde_ dużo liczenia na liczbach zmiennoprzecinkowych (na szczęscie mam na to mase czasu).

Ale jesli miałbym spoglądnąc na to krytycznie - to akurat ja nie miałem racji z STL(bo to w sumie wykorzystanie mechanizmów języka, a nie sam język C++) ani Ty (bo funkcje matematyczne to tez nie jest składnik _jezyka_ C a raczej dodatek).

Wspominałeś coś o plątaniu sie w spodniach ...

Hmm a czemu nie, o ile prościej jest napisać a+b, gdzie a i b to obiekty par liczb (powiedzmy współrzednych na ekranie LCD). Ale nie o to chodzi, chodzi raczej o ukryte manipulacje w tle, które produkują niepotrzene obiekty tymczasowe, najczesiej własnie przy kombinowaniu z operatorami. W sumie to sporo roboty jest, żeby stworzyc obiekt i go następnie za chwile zniszczyć.

Hmmm musze się przyglądnąc co się dzieje przy takim podejściu jak x=(a+b)*y (wszystko obiekty), czy aby a+b nie tworzy na stosie jakiegoś tymczasowego obiektu.

:) jednak: przy C mamy pełną jasnośc co do tego jak zostanie wykonana operacja (może za wyjątkiem konwersji/rzutowania, gdzie często łatwo zrobic błąd). Przy C++ mamy często przypadkowe błędy wynikające z nieznajomości pracy C++ przy manipulacji obiektami/wzorcami/whatever. W zasadzie C++ wydaje mi się w niektórych zastosowaniach bardziej niebezpieczny ( o ile niebezpieczeństwo zdefiniujemy jako nadmierne obciązenie pamięci). Choć jak najbardziej wygodny.

Alez ja cały czas pisze w kontekście AVR-C++. Mozliwe że się nie rozumiemy, jeśli rozmawiamy o C/C++ na duże pecety to ja się obydwoma rękami podpisuje pod wszystkim co piszesz. Ale na AVRy nie.

Szkoda, co prawda nie lubie pisać wyjątkami, ale sa sytuację, że bez nich jak bez ręki. W kazdym razie jak by niebyło to oficjalny składnik C++ więc skoro go nie ma na AVR to wygląda na to ze nie ma C++ tylko jakaś proteza :P

Pfuj, jakie to nieładne :) Nie jest to dla mnie żadną przeszkodą, ale fakt, że w winavr tego niepoprawili (chyba od dawna) świadczy o tym, że chyba jest mało developerów piszących w C++ na AVRy. Jesteś w mniejszości :P

Hmm zależy co kto pisze, w sumie cięzko mi sobie wyobrazić bardzo zaawansowany kod w paru kB flasha używający wszystkich możliwych funkcji C++. Jednak zwróć uwagę, ż mamy już pare ograniczeń: nie ma wyjątków, szkoda ramu na metody wirtualne (można sie kłucic czy faktycznie dużo zajmuja), nie ma new/delete z definicji w winavr (pewno mozna dorobic, nie robiłem tego, w zasadzie nie używam nawet malloc). Ten c++ na małe AVR po prostu nie jest tym samym, w dodatku stosowanie niektórych sztuczek w których powstają obiekty tymczasowe może doprowadzić do szybkiego wypełnienia RAMu ( o ile nie jest to optymalizowane, nie wiem).

Hmmm moment, 20% ? Jakoś cięzko mi tak podliczyc podobieństwa C++ i Javy. Wiele ksiązek dojavy rozpoczyna się od podsumowania róznić w stosunku do C++ lub co chwile w treści mamy ostrzeganie "tu jest troche inaczej". pewnie, że żaden ze mnie programista w javie bo ledwo liznąłem i cięzko się wypowiadać, ale moje zdanie jest takie, że mają bardzo dużo wspólnego. Choć zapewne po paru tysiącach linijek Javy mogę zmienić zdanie (choć już na dzień dzisiejszy mam ochotę rzucić ją w kąt i wrócić do C++). Zobaczymy za rok, na razi tematykę javy zamykam, bo za mało jeszcze wiem.

Wszystko ładnie, tylko podajesz proste przykłady, a wczesniej wpominałeś o znacznie bardziej rozbudowanym :): "sprawdzanie w czasie kompilacji hierarchii dziedziczenia za pomocą bardzo _pokrętnie_ skonstruowanego szablonu i _niecodziennego_ wykorzystania operatora sizeof" (podkreslenia moje). Ale masz oczywiście jak najbardziej racje, C++ jest do tego wymyślony i nie zmamierzam się spierać bo jest oczywiste, że C do pięt nie dorasta C++ przy elastyczności na etapie kompilacji kodu.

A swoją drogą ciakwostka: i w C da radę, o ile pamiętam FFTW jest napisanyw C i samodzielnie (choć oczywiście PO kompilacji, na żywym kodzie) się optymalizuje do CPU.

Hehe, powiedź to sąsiadowi z sąsiedniego biurka, swoją drogą pamiętam jak kolega debatował kiedyś 3 godziny z innym nad 4 linikowym kodem, który okazał się w końcu metodą zmiany 2 zmiennych bez użycia trzeciej (stara sztuczka z XOR). Wszystko ładnie i pięknie jesli piszesz sam, lub masz ludzi w zespole potrafiących jednym rzutem oka zrozumieć o co chodzi. Tak na marginesie: na jakiś 5 programistów w C++ w firmach jakich znam/znałem żaden już nie pisze z użyciem wzorców(za wyjątkiem bardzo prostych duperelek - nakaz szefów) bo statystycznie uzyskiwali mniejszą wydajność niż bez nich. Prawdopodobnie właśnie dlatego, że kod stawał się nieczytelny przez różne sztuczki. Pewnie że wina szefa, że nie ustandaryzował, ale co poradzić. Co nie zmienia faktu że to swietna zabawka :P

O fuj :) Zaciemnia jak diabli :) Ale to kwestia gustu.

Hmmm niewiem co masz na mysli: czy że za mało, czy że za dużo. Stawiam na to pierwsze i musze przyznać, że grzebanie w źródłach narzedzi GNU jest może przykładem sredniej wielkości projektów, ale bez wątpienia dużej ilości ... Grzebałem w kodach parudziesięciu programów unixowych i sporadycznie widac jakieś dodatki typu namespace/C++. A w ogóle to nie widziałem ani jednego korzystającego z STL (co nie znaczy że ich nie ma, ale pech - nie trafiłem :). C++ jest nadal mało popularny jako język apliakcji (popularnych), a jeśli w ogóle używany to na poziomie buildera i SQLa (gdzie podwójna pętla jest zadaniem dla szefa zespołu) a w takim stanie raczej przypomina wyłacznie C+obiekty. Niestety wyrosła konkurencja w postaci javy i C# oraz ogólne przechodzenie na .NET (choćby z powodu zaszpanowania przed konkurencją czy klientem). Szkoda, C++ był naprawde wielkim krokiem do przodu, dla niektórych za dużym.

To go usunę, żaden problem. Chyba że mam 50 plików .c, ale to chyba wychodzi poza ramy małego uC.

No masz, przecież dyskutujemy sobie swobodnie o wadach zaletach C/C++ a ty mi tu wmawiasz jakąs "obronę z uporem" :). Ależ ja jestem otwarty na C++ tak samo jak na C w przypadku uC. W sumie nie chce jakiejś wojny wywoływać, tylko posłuchac o ciekawych rozwiązaniach i po drodze troche poprowokować ... :P

Owszem, szablony są wazne, pozwoliłem sobie troche przesadzić w nazwie. Nie zmienia to faktu, że C++ w całości jest trudny w użyciu na uC. Faktycznie pozostają wyłącznie szablony i może obiekty. Jeśli z uporem podkreślasz ich zalety, to muszę zrobić pare testów i może też zaczne powszechnie korzystać. Człowiek się uczy cały czas, prawda ? :)

nie nie, źle to nazwałem, chodzi o komórki pamięci pełniące role "strowników" hardware w mikrokontrolerze. Ale mniejsza o to, bo widze, że coś namieszałem z tym kawałkiem i się nie dogadamy.

Z paru innych rzeczy też (wcześniej pisałem). Czy połowa to znowu kwestia gustu i przyzwyczajeń.

Jasne, ale w sumie o ile to bardziej bedzie bolesne od C/C++. Niektórych rzeczy nie warto robic za nawet duże pieniądze :). Kiedyś widziałem w sklepie internetowym koszulkę z napisem "Jestem szmata, pisze w VB". Coś w tym jest :) Inna sprawa, że głupio taką zakładac, jeśli 99% społeczeństwa rozumie tylko część przed przecinkiem...

Ależ nie twierdze, że nie nalezy tego używać. Chyba musze posumowac dyskusję żeby była jasnośc :)

Ja :)

A teraz podsumowanie z mojeje strony:

a) jestem absolutnie za pisaniem w C++ na wiekszych maszynkach (większa maszynka=>64KB RAM, z reszta silnie zalezy od problemu). Stosowaniem takich technik, jakie udostepnia dany jezyk. C jest po prostu zbyt niebezpieczny na _duże_ projekty.

b) jestem absolutnie za używaniem wzorców przy pisaniu kodu na małe uC. Z jednym małym wyjątkiem: że po roku czasu patrząc w kod będe wiedział o co chodzi. Na razie tego nie robie, bo nie było potrzeby, pierwsza się pojawiła przy dobieraniu wielkości licznika w poprzednim wątku i w tej chwili wacham się nad przejściem na kompilator C++. Zobaczymy jak bardzo będzie to bolesne.

c) nie lubie języków BASCOM/whatever bo nie dają mi swobody implementacji na niskim poziomie i często nie wiem, w jaki sposób działa dany fragment. Pisanie wiekszych projektów mija się z celem, w zasadzie brak wsparcia ze strony języka.

d) Nie jestem wrogiem C++, wręcz przeciwnie większośc programów pisze wlasnie w C++ i nie zamierzam się z tego wycofywać w najbliżyszm czasie (chyba że .NET zrobią na unixa, ale nawet wtedy chyba nieprędko). Zaznaczam jednak, że wzorców używam w zasadzie głównie do implementacji algorytmów zniezależnych od typów. Jakoś nie mogę się przekonać co do przejrzystości kodu z użyciem wzorców w innych rolach.

e) pisuje w C głównie na kontrolery AVR, bo po prostu jest tak dla mnie przejrzyściej. Skoro twierdzisz, że wzorce są takie świetne i nie utrudniają życia/kompilacji/wielkości kodu, to postaram się do nich przekonać.

f) Obawiam się, że zanim zaczne się bawic na poważnie w C++ na AVR to przejdę już na ARM i wtedy problemu nie będzie (po prostu będę miał pełny C++).

Pozdrawiam :)

Ale się rozgadalismy...

Reply to
Sebastian Bialy

Akurat sinusa się prosto liczy, niedawno nawet opisywałem algorytm. :-)

Tu sprawa wcale nie jest jasna: kiedyś długo dyskutowałem z kimś na ten sam temat, ale sprawa zredukowała się do udzielenia odpowiedzi na pytanie, czy STL-owy string to część C++, czy też niezależny od samego języka program. Każdą z dwu możliwych odpowiedzi można poprzeć bardzo silnymi argumentami, więc sprawa została nierozstrzygnięta. Ja jestem za drugą z tych możliwości, ale "obóz przeciwny" też ma dużo racji. Ale widze, że jesteś w moim. ;-)

Nie należy używac mechanizmów, których zasady działania się nie rozumie.

Wiedziałem, że się droczysz. ;-) Bez wyjątków daje się żyć i na dużych maszynach, więc na mikrokontrolerach tym bardziej.

Chyba nie istnieje na Ziemi kompilator będący całkowicie zgodny ze standardem C++ i implementujący wszystkie własności tego języka, np. konstrukcję "export template" -- mówię całkowicie poważnie. :-)

Gdy ostatnio zaglądałem w "nowe" inkludy, to właśnie tak to zrobili:

nowy_inklud = extern "C" {

#include "stary_inklud.h" }

:-)

Bez problemu można to sobie dopisać, tylko mając 128 bajtów RAM nie bardzo jest czym zarządzać. :-)

Owszem, maksymalnie 20%. Liczą się nie tylko podobieństwa strukturalne, ale głównie wyrażalność -- w C++ masz do dyspozycji cały arsenał technik, które nie mają swoich odpowiedników w Javie.

Wbrew pozorom on nie jest bardziej rozbudowany, jeśli chodzi o wielkość kodu, to zaledwie ~10 linijek -- znacznie mniej, niż zajmie rozwiązanie każdego z wcześniejszych przykładów. Jego "pokrętność" sprowadza się do przebłysku geniuszu autora, a nie do wykorzystania jakiegoś olbrzymiego i nieczytelnego kodu. Masz poniżej moją implementację (choć nie ja wpadłem na tę technikę), spróbuj dojść, jak to działa. :-)

struct aux_large_type { char m_Dummy[2]; };

template <class U, class V> struct aux_affinity_conversion {

private:

static char check(V*); // Not implemented, only the signature is used static aux_large_type check(...); // Not implemented, only the signature is used

public:

enum { is = (sizeof(check(static_cast<U*>(0))) == sizeof(char)) }; };

Poza tym rzekoma "pokrętność" nie jest widoczna dla końcowego użytkownika -- on pisze tylko "affinity<pierwszy_typ, drugi_typ>::is_derivation" i w czasie kompilacji dostaje stałą boole'owską z odpowiedzią na pytanie o istnienie relacji dziedziczenia typu drugi_typ z pierwwszy_typ, której może użyć np. do parametryzowania innego wzorca.

Swego czasu zademonstrowałem im kilka tego typu technik... a później się na mnie długo patrzyli jak na raroga. ;o) Ale zrozumieli i teraz sami używają. :-)

Niestety niewielu ludzi potrafi to robić porządnie albo nawet nie wie o istnieniu takich technik w C++ -- to zostało opracowane dopiero w tym wieku. Nie żeby to była jakaś sztuka tajemna, po prostu te techniki miały zbyt mało czasu, by się upowszechnić.

Wydajność pisania kodu? Jeśli tak, to uwierzę. Wydajność programu nie miała prawa spaść, jeśli spadła, to zrobiono coś bardzo, bardzo źle.

Przecież tego kodu nie widać -- jest zamknięty w odpowiednim nagłówku, a używa się tylko parametryzacji tego szablonu. Parametryzacje są bardzo czytelne, a przynajmniej powinny być.

Hmm... :-)

Za dużo.

Szkoda.

Szpan pewnie też jest tu istotnym czynnikiem, ale .NET to naprawdę porządnie zaprojektowana platforma, więc bardzo dobrze jej życzę. :-)

Nie zgodzę się, C++ pod względem jakości projektu języka jest sporym krokiem wstecz, ja wolę Adę. A pod względem nowych mozliwości -- to fakt, doszło bardzo dużo nowych rzeczy, w C nieosiągalnych.

Nie usuniesz, bo nie będziesz o nim wiedział. Dowiesz się o jego istnieniu będąc w połowie drogi na Księżyc, niesiony pędem eksplozji kotła parowego, który Twój sterownik wysadził. ;-) W C++ dzięki przestrzeniom nazw takie coś nie może zaistnieć, bo użytkownikom zasadniczo nie wolno niczego dokładać do STD.

Dlaczego? Nieukończony jeszcze kod mojego mp3-playerka to ~30 plików, niestety w C (na 8051 za darmo jest dostępny tylko SDCC).

W całości tak.

Spodoba Ci się i będzie nas tu dwuosobowa mniejszość, choc Jerry kiedyś coś wspominał, że go nawróciłem na C++ w NIOSie. ;-)))

Ja też nie spodziewam się wielkich przyjemności, ale jeśli będzie trzeba, to rzecz jest wykonalna.

Dziękuję, bez reszty się obędę. ;-)

Ani ja, co nie zmienia faktu, że w razie potrzeby mogę w nich pisać.

To jest jedyny (i do tego bardzo dobry) sposób rozwiązania Twojego problemu z licznikiem, więc masz już cos na zachętę. ;-)

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

Myslisz, że tylko sin potrzebuje :) ? Mam za zadanie liczyc funkcje, gdzie jest: logarytm przy podstawie narzuconej, prawdopodobnie jakaś funkcja składana z sin i paru przekształceń, i jeszcze cos, czego pomysłodawca nie zdefiniował: "jeszcze pomysle". Hmm.... chyba jednak standardowa biblioteka C pójdzie w obroty, jeszcze nie upadłem na głowę żeby pisać wszystko na bitach/bajtach/+/- ... :P

Heh, powiedź to miszczom używająym Delphi i stringów w środku :) na palcach jednej ręki policzyłbym wśród znajomych programistów zaprzątających sobie głowę jak to działa. Co nie przeszkadza im wszystkim powszechnie używać. Swego czasu pamietam moje boje kiedy tłumaczyłem po co jest konstruktor kopiujący kiedy obiekt allokuje jakieś zasoby - do nie ktorych po prostu nie trafia, jesli pisza przez 5 lat "OnClick->SELECT FROM * ...". ja myslę, że programiści nie mający pojęcia jak działa kompilator są w znacznej większości na rynku. W dodatku wycięcie wskaźników z języków takich jak java i C# tylko pogłębia zapaść (acz nie jestem przeciwnikiem znikania wskaźników - tylko boleje nad faktem braku znajomości mechanizmów niskiego poziomu).

Masz racje, ale to wynik przyzwyczajenia. Przypuszczam że ktoś wychowany na wyjątkach nie wyobraża sobie zycia bez nich.

Ale wyjątki to raczej się implementuje :P Ale dobra, niech będzie że faktycznie standard C++ to na razie świstek papieru a nie rzeczywistość.

A owszem, tylko że niepowinien tego robic programista a producent kompilatora.

Można, można :) Zalezy co jest wazniejsze: czy ilośc RAM, czy "profesjonalnośc" kodu - nie jesten programista C bije pokłony do wydruku kodu allokującego 2-wymiarową tablicę :P Na razie nie trafiłem na małym AVR na potrzebę malloc'a,ale już na AtMega162 z zewnątrznym RAMem - a i owszem, jak bez ręki.

Nie o 1 w nocy ... :) ja już nie mam sił na myslenie, przed chwilą pomyliłem w kodzie true z false i po prostu nie daje rady ... ale zerknę, choć z wzorców żaden ze mnie specjalista.

Owszem, ale okazuje się, że wzorce okazały się zbyt skomplikowane dla szarego programisty. Niestety filozofia pisania komercyjnych aplikacji sprowadza się do prostych pomysłów typu SQl+zdarzenia GUI. Jesli przez 5 lat pisze wyłacznie w tym zakresie aplikacje, to po prostu nic go nie przekona do nauki wzorców (może wywaleniez roboty i szukanie nowej dla motywację).

Tak. Mój znajomy twierdzi, że po prostu były niejasności i różne koncepcje, jak również spore dziury w wiedzy pomiędzy zespołem. A w zasadzie wszystko można zrobić bez wzorców, tyle że mniej elegancko. Ale jak się okazało w tych warunkach - szybciej.

Owszem, fajna zabawka, ale na razie działa sensownie tylko na Win, a Mono jakoś się robi i robi i nie może wreszcie się przebić powaznie jako alternatywa, z resztą jeśli się nie będa kompilowac programy okiemnkowe pod mono, to daleko niezajedzie. Ja troche poczekam, bardzo nie lubie zamykac sobie kodu tylko na win (takie lekkie zboczenie).

Miałem dopisać "dla programistów C". Co do Ady - nie znam. I nie poznam, bo nie ma zaplecza w postaci bibliotek/algorytmów w takiej ilości jak C. A może się mylę ?

Hmm... zobaczymy. Na razie mam wazniejsze sprawy na głowie, ale w wolej chwili ...

Problem chwilowo rozwiązany inaczej - znalazlem troche mocy obliczeniowej w głównej pętli i jednak kręcę 4 bajtami. Natomaist rozwiązanie to jest mało eleganckie więc może w wolnej chwili się pobawie.

Reply to
Sebastian Bialy

U mnie podobnie (brak czasu na R&D) - jak powylaczalem niepotrzebne bzdury w kompilatorze (typu wyjatki itp), to kod sie zrobil sensownie krotki i proste rzeczy byly obiecujace ;-) A ze niedlugo bedzie trza siakies okienka na Niosa napisac (bo cos wyswietlic na LCD 320x240...) to sie zabiore za c++ w embedded world na powaznie - po roku...

Reply to
jerry1111

Fajny ten internet - nie zdaze sie Piotra zapytac o dobra ksiazke i juz mam odpowiedz ;-) A czy jest taka ksiazka (w zasadzie wiedza czy jest, to tez cenna informacja) ktora by opisywala uzywanie C++ w malych procesorkach? Czyli co mozna, czego lepiej nie robic - wiesz, takie male kompendium wiedzy coby jeszcze raz kola nie wymyslac.

Reply to
jerry1111

Niestety niczego mi na ten temat nie wiadomo. Jeśli mam na danym procku C++, to po prostu siadam i w nim piszę, a kod wychodzi taki, jaki chciałem mieć. Nie zauważyłem większych różnic w podejściu w porównaniu z większymi maszynami. Nie używam tylko wyjątków, typowania dynamicznego i metod wirtualnych, bo na ośmiobitowcach zazwyczaj jest za mało pamięci na dane. Wykorzystuję za to różne niskopoziomowe mechanizmy standardowe, których się praktycznie nie używa na większych maszynach, np. placement new. Cała reszta bez zmian, zwłaszcza szablony.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.