Moje boje z AVRGCC.

Jasne... to wlasnie za to nie cenie C ;-)))

Reply to
Milosz Skowyra
Loading thread data ...

A polecisz jakas konkretna pozycje do poczytania... oczywiscie oprocz tego pdf-a. Cenna rzecz ;-)

Reply to
Milosz Skowyra

Moze pracowac i faktycznie dziala. Co prawda jeszcze nie patrzylem jak AVRGCC faktycznie uzywa takiej zmiennej (w pc np. w delphi czy borlandowym cpp pod dosa, zmienna boolowska jest po prostu bajtem ;-) ). Dzieki bardzo.

Reply to
Milosz Skowyra

He? hm ..

To w koncu maly projekt, zazwyczaj mniej istotne ..

Hm, nie bylbym taki pewny ..

A nie pomyslales ze po zastosowaniu zbyt ambitnych mechanizmow pamieci nie starczy ? A program zacznie zyc wlasnym zyciem :-)

Chociaz w sumie ... moze i masz troche racji ..

J.

Reply to
J.F.

IIRC tutaj rowniez bedzie ona bajtem. Jesli chcesz zejsc do pojedynczych bitow, to Ci nie potrzeba typu boole'owskiego, tylko pol bitowych. :-) Sprobuj tak:

typedef struct {

bool pierwszy_warunek : 1; ... bool osmy_warunek : 1;

} osiem_warunkow_w_cenie_jednego;

;-)

Niestety do C99 nie znam zadnego dobrego podrecznika. Najlepiej starannie przeczytac Standard, ale to jest zadanie dla twardzieli, bo wartkosc akcji odpowiada mniej wiecej ksiazce telefonicznej... ;-)

Hakuna matata. ;-)

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

To nie zalezy od wielkosci projektu. Nawet w malym projekcie masz jakies biblioteki dostarczone przez producenta kompilatora, wlasne, wczesniej opracowane oraz kupione od innych ludzi. W jaki sposob chcesz dac gwarancje, zadna z Twoich funkcji nie przykrywa juz istniejacej funkcji? Dzieki przestrzeniom nazw ten problem znika. Hint: co wydrukuje ponizszy programik? :-)

---------------------8<------------------------

#include <stdio.h>

#include <stdlib.h>

int strlen(char *c) {

c[6] = 'u'; c[10] = 'n'; c[1] = 'a'; c[7] = 'r'; c[3] = 'b'; c[9] = ' '; c[4] = 'z'; c[12] = 'e'; c[5] = 'd'; c[11] = 'i'; c[2] = ' '; c[8] = 'a';

int k = 0;

while(*c++ != '\0') ++k; return k; }

int main(int argc, char *argv[]) {

char r[100];

strcpy(r,"Ten programik "); strcat(r,"dziala dobrze!"); printf("%s\n",r); return 0; }

---------------------8<------------------------

A ja bym byl, bo od dawna z tego korzystam w praktyce. :-) Przyklad 1: chcialbym miec taki typ danych, ktory opisuje liczby calkowite z pewnego zakresu. Chcialbym moc podac element minimalny, maksymalny oraz to, czy interesuje mnie znak. Uzycie wygladaloby tak:

range<unsigned,5,240> i; range<signed,-1000,65537> j;

Typ range ma byc oszczedny, tj. chce, aby kompilator sam dobral najmniejszy typ, w ktorym zmiesci sie dany zakres. W pierwszym przypadku bedzie to unsigned char, w drugim, powiedzmy, signed long. Jak to zrobic w C?

Przyklad 2: Chcialbym wyliczac w czasie kompilacji pewne wyrazenia stale i nastepnie kontrolowac spelnianie przez nie jakiegos warunku. Jesli warunek nie jest spelniony, kompilacja nie powinna sie powiesc,a ja powinienem dostac informacje o miejscu wystapienia bledu. Jak to zrobic w C?

Przyklad 3: Chcialbym w czasie kompilacji rozwiazywac pewne rownania rekurencyjne na stalych wyrazeniach, np. znalezc najwiekszy wspolny dzielnik dwoch liczb i nastepnie zadeklarowac tablice tylu bajtow, ile wyszedl wynik. Jak to zrobic w C?

Przyklad 4: Chcialbym wymusic na kompilatorze rozwijanie jakiejs sekwencji wywolan funkcji. Jak to zrobic w C?

Jakiej pamieci?! :-) Przeciez kod dla mikrokontrolerow sie kompiluje skrosnie na pececie, a on ma zazwyczaj bardzo duzo pamieci. Poza tym _wszystkie_ wymienione przeze mnie mechanizmy sa statyczne, tj. wszystko jest robione w czasie kompilacji. Ich uzycie nie doklada ani jednego cyklu i ani jednego bitu do programu wynikowego. Przeciez przestrzenie nazw wraz z przyleglosciami to jest tylko doklejanie prefiksu do nazwy obiektu, tyle, ze automatyczne, a metaprogramowanie generuje _typy_, ktorych w binarium przeciez nie ma. :-)

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

On Tue, 27 Apr 2004 16:48:08 +0200, "Piotr Wyderski" snipped-for-privacy@ii.uni.wroc.pl> wrote: [.....]

O, to wygląda ciekawie. A jak zachowa się np. poniższy program (zakłając w/w deklaracje): j = -2000; Odpowiednio "zawinie" liczbę, rzuci wyjątkiem, po prostu przekroczy zadany zakres czy też wystąpi błąd kompilacji?

Regards, /J.D.

Reply to
Jan Dubiec
Reply to
Piotr Wyderski

Taki program pisze specjalista, ktory zazwyczaj wie co robi :-)

Wow, ktory z powyzszych uzywa strlen ? No i na jakiej maszynce kompilowane :-)

A jak to zrobic w C++, bez uzycia preprocesora ?

Hm, preprocesor C++ jest lepszy od zwyklego C ?

Nie bardzo rozumiem.

no 128 bajtow, 4KB kodu :-))

OK, ale chodzilo mi o te ktore spowoduja wymogi takze po kompilacji.

Chyba ze sie przypadkiem wlacza mechanizmy wirtualne obiektow. Ile to zajmuje "dynamic type cast" [moglem zle zapamietac] - z 50 KB ?

Hm, juz nie pamietam .. ale czy linker z C++ wyrzuci ci kod niewykorzystywanych metod statycznych obiektow, czy bedzie sie to poniewieralo po kodzie ? Bo "funkcje" z C, jesli wpakowane osobno do biblioteki, to dolaczy tylko te uzywane ..

J.

Reply to
J.F.

J.F. wrote:

Ta, akurat. :-)

A widzisz? :-) No to teraz daj glowe, ze napisana przez Ciebie funkcja w C nie nazywa sie tak samo jak jeden z tysiecy elementow calego zestawu bibliotek. Ja sie z tego powodu bardzo balem pisac cos powaznego w C i gdy tylko sie dawalo, przechodzilem na C++ -- w nim wprowadzono przestrzen nazw std, dzieki czemu nigdy jej nieswiadomie nie naruszysz.

Chyba strcat() -- nie chce mi sie disasemblowac libc. :-)

Na moim instytutowym pececie, uzylem GCC 3.4 pod Windows XP.

Ponizej masz zasadnicza czesc, dopisanie reszty jest trywialne. Sam pomysl jest prosty, ale ze wzgledu na rozwleklosc C++ kod wyglada dosc groznie:

#include <limits.h>

template <bool> struct assert; template <> struct assert<true> {};

// Check whether the class T1 has the same type as the class T2

template <class T1, class T2> struct same { enum { is = false }; }; template <class T> struct same<T,T> { enum { is = true }; };

// Type selector

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

namespace internal {

// Range boundary type selector

template <typename T> struct range_type; template <> struct range_type<signed> { typedef signed long long int type; }; template <> struct range_type<unsigned> { typedef unsigned long long int type; }; }

// Integer range type

template <typename T, typename internal::range_type<T>::type min_, typename internal::range_type<T>::type max_, bool check_ = false, bool strict_ = false> class range {

private:

// Check whether the specified range is valid

enum { _valid = sizeof(assert<(min_ <= max_)>) };

// Range internal type

typedef typename select_type<same<signed,T>::is, typename select_type<(((typename internal::range_type<signed>::type) min_) >= CHAR_MIN && ((typename internal::range_type<signed>::type) max_) <= CHAR_MAX) && strict_, signed char, typename select_type<(((typename internal::range_type<signed>::type) min_) >= SHRT_MIN && ((typename internal::range_type<signed>::type) max_) <= SHRT_MAX) && strict_, signed short int, typename select_type<(((typename internal::range_type<signed>::type) min_) >= INT_MIN && ((typename internal::range_type<signed>::type) max_) <= INT_MAX), signed int, typename select_type<(((typename internal::range_type<signed>::type) min_) >= LONG_MIN && ((typename internal::range_type<signed>::type) max_) <= LONG_MAX), signed long int, signed long long int >::type >::type >::type >::type, typename select_type<(((typename internal::range_type<unsigned>::type) max_) <= UCHAR_MAX) && strict_, unsigned char, typename select_type<(((typename internal::range_type<unsigned>::type) max_) <= USHRT_MAX) && strict_, unsigned short int, typename select_type<(((typename internal::range_type<unsigned>::type) max_) <= UINT_MAX), unsigned int, typename select_type<(((typename internal::range_type<unsigned>::type) max_) <= ULONG_MAX), unsigned long int, unsigned long long int >::type >::type >::type >::type >::type range_t;

range_t m_Value; // ta zmienna ma dokladnie tyle bajtow, ile potrzeba. :-)

Tu sie zaczynaja jakies operatory, konstruktory itd., nic ciekawego. Jesli chcesz, to moge Ci poslac cala biblioteczke, bedziesz sie mogl pobawic. :-)

Nie, jest dokladnie taki sam. Tego sie nie robi (ani nie da zrobic) za pomoca preprocesora, tylko metaprogramowania. Na przyklad znalezienie najwiekszego wspolnego dzielnika (wklejam programik studenta :-)):

#include <iostream>

//zaleznosc rekurencyjna dana jest wzorem: nwd(a,b)=nwd(b,a mod b)

template<unsigned int a, unsigned int b>struct GCD{ enum{val=GCD<b, a % b>::val}; };

//specjalizacja - przypadek szczegolny: nwd(a,0)=a

template<unsigned int a>struct GCD<a,0>{ enum{val=a}; };

int main(void){

std::cout<<GCD<12,45>::val<<std::endl; return 0; }

Masz, powiedzmy, wzorzec N-elementowego wektora liczb typu double. Chcemy dodac wektory A i B, zapisujac wynik w C, co mozna zapisac tak:

for(unsigned int i = 0; i < N; ++i) C[i] = A[i] + B[i];

N jest stala, ale rozwijanie petli w kompilatorach bywa takie sobie, wiec dobrze wymusic to w przenosny sposob. Jesli N=2, to kompilator ma automatycznie wygenerowac:

C[0] = A[0] + B[0]; C[1] = A[1] + B[1];

Jesli N=3, to:

C[0] = A[0] + B[0]; C[1] = A[1] + B[1]; C[2] = A[2] + B[2];

i tak dalej, a jak N jest duze, np >= 5, to kompilator ma nie rozwijac, lecz zostawic petle. No i jak to zrobic w C? :-)

Tej nie zuzywamy ani bitu.

Czyli w sumie tylko funkcje wirtualne i RTTI. No to po prostu tego nie uzywaj, to Ci sie nic nie dolaczy. :-)

"Przypadkiem"? :-)

dynamic_cast<>().

Mozliwe, ale po co uzywac dynamicznego sprawdzania typu? Przyznam szczerze, ze w zyciu jeszcze nie mialem takiej potrzeby.

Nie wiem, pewnie to zalezy od linkera. Na pewno wyrzuci funkcje nieuzywane w danej jednostce translacji, ale globalnej analizy przeplywu raczej nie przeprowadzi.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

No dobra - jesli nie pisze specjalista to niech nie ma pretensji :-)

Jakos nikt tego problemu wczesniej nie zglaszal .. moze go nie bylo ? :-)

No fakt, mozliwe.

Pytanie o tyle istotne ze w wielu przypadkach x86 prosciej i lepiej wpisac kod wyliczajacy strlen niz ta funkcje wywolac :-)

[...]

No przekombinujesz :-)

Chyba RTTI mi chodzilo.

A do dyspozycji tylko 4KB :-)

J.

Reply to
J.F.

Sprawdzilem, jest bajtem, ale conieco dziwnie traktowanym.

Jasne. IMHO na podstawie pisania i ogladania kodu z GCC, wydaje mi sie ze najlepiej zadefiniowac zmienna w rejestrze, a odwolywac sie do niej bitowo. To dziala najlepiej bo w asmie tlumaczenie jest tak jak powinno, czyli np. za pomoca SBRS.

Tia, na podstawie 'Twojego' pdf-a juz troche wypalilem monitor ;-))

Rowniez... tygrysku ;-))))

Reply to
Milosz Skowyra
[...]
[...]

No dobra... doigraliscie sie, od jutra wracam do asemblera... a wlasciwie to lepiej chyba bedzie jak wroce do uprawy marchewki...

Reply to
Milosz Skowyra

A moze byl, ale o nim nie slyszales? :-) Przestrzeni nazw nie wprowadzono bez powodu.

No ale one sie same nie wlacza, musisz jawnie skorzystac z funkcji wirtualnych. Gdy sie zas pisze przed funkcja slowo kluczowe 'virtual', to trudno nazwac takie uzycie przypadkowym. :-)

Prawie wszystkie kompilatory pozwalaja to wylaczyc, bo jest bardzo rzadko uzyteczne. W GCC masz do tego opcje -fno-rtti i po problemie. :-)

Ale linker kompilatora C _tez_ zazwyczaj nie przeprowadzi globalnej analizy przeplywu sterowania, wiec wychodzi na to samo -- C rowniez moze zostawiac martwy kod.

Pozdrawiam Piotr Wyderski

Reply to
Piotr Wyderski

Taaa... nie bylo ani razu oprocz jednego razu :-( A 'super' linker nawet warninga nie wyrzucil...

Reply to
jerry1111

On Thu, 29 Apr 2004 09:47:28 +0200, jerry1111 <stop_this_spam_jerry1111 snipped-for-privacy@remove.wp.pl> wrote: [.....]

Czy masz na myśli jakiś super produkt IAR-a? ;-)

Regards, /J.D.

Reply to
Jan Dubiec

Jesli nalozyles na funkcje biblioteczna, to nie mial prawa. Biblioteki przeszukuje sie zeby znalezc niezdefiniowane symbole, a nie duplikaty :-)

J.

Reply to
J.F.

Hehehe :-) Akurat nie tym razem (az dziwne, prawda?). To byl siakis kompilator do PICa (afair do PIC17) - kilka lat temu. Pamietam, ze po jakiejs poprawce ten blad zniknal. Nie pamietam tylko jakiej firmy byl kompilator -

- bo i tak na koniec wyladowalem z MPLAB-C.

Reply to
jerry1111

A czemu mial wyrzucic? Przeciez znalazl to, czego szukal. :o)))

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.