|
#1
|
|
|
|
|
Na co dzien uwielbiam pisac w C++ ale i tez musze pisac w C#, C++CLI.
I zastanawia mnie czy kiedykolwiek C++ bedzie mialo refleksje chociaz etapu kompilacji. W MPI(CH) .NET pieknie widac jak bardzo upraszcza to programowanie i jak bardzo czyni kod czytelnym wzgledem MPI(CH) w zakresie MPI .NET Send, Recive, Broadcast<type>() vs MPI_TYPE_STRUCT i okreslanie typow atrybutow z reki i ich adresow. Oczywiscie w C++ mozna uzyskac namiastke uzywajac do tego wzorców i np specjalizacji z metaprogramowaniem ale nadal bedzie trzeba okreslac w jakis sposób elementy struktury, deklarowac je. Czy C++ bedzie miec kiedykolwiek refleksje czasu kompilacji czy jest to nie wykonalne ? |
|
|
|
#2
|
|
|
|
|
> Na co dzieĹ uwielbiam pisaÄ w C++ ale i teĹź muszÄ pisaÄ w C#, C++CLI.
> I zastanawia mnie czy kiedykolwiek C++ bÄdzie miaĹo refleksje chociaĹź > etapu kompilacji. > > W MPI(CH) .NET piÄknie widaÄ jak bardzo upraszcza to programowanie i jak > bardzo czyni kod czytelnym wzglÄdem MPI(CH) w zakresie MPI .NET Send, > Recive, Broadcast<type>() vs MPI_TYPE_STRUCT i okreslanie typow > atrybutow z reki i ich adresow. > > OczywiĹcie w C++ moĹźna uzyskaÄ namiastkÄ uĹźywajÄ c do tego wzorcĂłw i np > specjalizacji z metaprogramowaniem ale nadal bÄdzie trzeba okreĹlaÄ w > jakis sposĂłb elementy struktury, deklarowaÄ je. > > Czy C++ bÄdzie mieÄ kiedykolwiek refleksje czasu kompilacji czy jest to > nie wykonalne ? nie znam sie za bardzo na tych tematach ale jak sobie wyobrazasz refleksje w c (vel c++) Wydaje mi sie ze zeby cos poddawac owej reflesji to cos musialby niesc dynamicznie informacje o typach, nazwach itp - w zasadzie fakt, nie tyle dynamicznie (tj nie wszystko to musi byc dynamicznie, bo nie koniecznie skompilowany program musi tych danych uzywac) ale trzeba by zaszywac informacje np o nazwach i typach w pilkach binarnych - wersje debug chyba to robią trzebaby doczytac. Co do informacji o zmiennych dynamicznych taka informacja musialaby byc chyba tez dynamiczna co spowalnialoby wykonanie. Ciekawy skadinad temat - ja rozumiem go w wersji "zaszywanie informacji o 1. typach 2. nazwach w pilkach binarnych - mozna przemyslec" fir |
|
#3
|
|
|
|
|
arturbac pisze:
> Na co dzien uwielbiam pisac w C++ ale i tez musze pisac w C#, C++CLI. > I zastanawia mnie czy kiedykolwiek C++ bedzie mialo refleksje chociaz > etapu kompilacji. > > W MPI(CH) .NET pieknie widac jak bardzo upraszcza to programowanie i jak > bardzo czyni kod czytelnym wzgledem MPI(CH) w zakresie MPI .NET Send, > Recive, Broadcast<type>() vs MPI_TYPE_STRUCT i okreslanie typow > atrybutow z reki i ich adresow. > > Oczywiscie w C++ mozna uzyskac namiastke uzywajac do tego wzorców i np > specjalizacji z metaprogramowaniem ale nadal bedzie trzeba okreslac w > jakis sposób elementy struktury, deklarowac je. > > Czy C++ bedzie miec kiedykolwiek refleksje czasu kompilacji czy jest to > nie wykonalne ? IMHO nie bedzie. jest to typowe dla róznych form interpreterów. Kod maszynowy (nawet z virtualkami itd) nie zawiera takich informacji. Bedzie w "interpretowanym C++" (czy managed tu podpada - nie wiem) tylko to juz nie bedzie C++. Sa namiastki, np. wiem o projekcie (na gruncie BCB & Delphi) ktory w oparciu o MAP z linkera nadbudowuje troche informacji (ile jest w stanie). Z tego korzysta jakis obslugiwacz bledow. Tu po raz kolejny bije to, ze w C++ (mowa o standardzie - bywa w dialektach) obiekty nie maja wspólnego przodka. W razie gdyby mialy, moglo by to byc jakies zaczepienie do takich pomyslow. Zaakcentowalem troszke bardziej obsluge bledow a nie normalna prace, ale to obecnie robie i jest jeden z punktow gdzie refleksja by byla pomocna. Inny trick, to troszke z makr preprocesora, __LINE__, __FILE__ __FUNCTION__ (chyba nowsze i niezupelnie standardowe), oraz ##arg - daje namiastke tej informacji. Ale wiadomo co myslec o makrach |
|
#4
|
|
|
|
|
On 3 Mar, 10:01, Jacek Czerwinski <x> wrote:
> > Czy C++ będzie mieć kiedykolwiek refleksje czasu kompilacji czy jest to > > nie wykonalne ? > > IMHO nie bedzie. jest to typowe dla róznych form interpreterów. Nie. Np. w Adzie jest coś co się nazywa ASIS (Ada Semantic Interface Specification) i umożliwia analizę elementow kodu np. w postaci XML. W szczególności używa się tego do generowania dokumentacji, ale skoro można zrobić dokumentację, to można też np. serializator. Naprawdę dobre zastosowanie tego można znaleźć w dokumencie "Using ASIS to Generate C++ Bindings" - tytuł mówi sam za siebie. To nie jest wsparte bezpośrednio przez sam język, ale jest na to standard ISO i w szczególności narzędzia związane GNAT to obsługują. Jedynym powodem dla którego nie ma czegoś takiego w C++ jest fakt, że nikt tego nie zrobił a nie to, czy obiekty mają wspólnego przodka albo czy jest VM, itd. - to nie musi być w całości w run-time. Natomiast pytanie czy coś takiego będzie w C++ jest bardzo dobre. Moja opinia: nie będzie. |
|
#5
|
|
|
|
|
>
> Jedynym powodem dla którego nie ma czegoś takiego w C++ jest fakt, że > nikt tego nie zrobił a nie to, czy obiekty mają wspólnego przodka albo > czy jest VM, itd. - to nie musi być w całości w run-time. > w wiki w artykule o refleksji jest polozony nacisk na 'modyfikowanie programu w trakcie dzialania' - tego w jednorazowo kompilowanym kodzie nie da sie oczywiscie zrobic - ale jak mowie refleksja typu 'read' zasadniczo jest mozliwa - trzeba by tylko sie zastanowic co da sie zrobic statycznie a czego ew nie da sie zrobic statycznie poki co c/c++ jest z grubsza rzecz biorac statyczny wiec chyba i cala ta refleksje mozna by zrobic calkiem statycznie - ale ew trzeba bedzie pomyslec ntt |
|
#6
|
|
|
|
|
W dniu 2010-03-03 10:15, Maciej Sobczak pisze:
> On 3 Mar, 10:01, Jacek Czerwinski <x> wrote: > >>> Czy C++ będzie mieć kiedykolwiek refleksje czasu kompilacji czy jest to >>> nie wykonalne ? >> >> IMHO nie bedzie. jest to typowe dla róznych form interpreterów. > > Jedynym powodem dla którego nie ma czegoś takiego w C++ jest fakt, że > nikt tego nie zrobił a nie to, czy obiekty mają wspólnego przodka albo > czy jest VM, itd. - to nie musi być w całości w run-time. Dokladnie nie doczytli przedmowcy nie mowie o Runtime Reflection ale o chociaz CompileTime Reflection. Poprzez Compile Time Reflection rozumie prymitywne przeiterowanie skladowymi obiektow w formie metaprogramowania. To musi byc mozliwe dlatego ze do kompilacji wymagana jest definicja obiektow i musza byc znane rozmiary i musza byc znae offsety skladowych obiektu. Co wazne nie jest potrzebna implementacja a jak napisalem definicja typu klasy/struktury. Kompilator aby skompilowac kod musi znac definicje klasy/struktury a jesli ja zna to na tym etapie w formie meta programowania np poprzez specjalizacje mozna by iterowac po skaldowych. Podobnie z enum podczas kompialcji zna calosc wyliczen wiec i nie istnieje powod dla ktorego w formie metaprogramwoania/specjalizacji klasy iteracji nie moglby udostepnic nazw wyliczen. > Natomiast pytanie czy coś takiego będzie w C++ jest bardzo dobre. Moja > opinia: nie będzie. Szkoda wielka. |
|
#7
|
|
|
|
|
> W dniu 2010-03-03 10:15, Maciej Sobczak pisze:
[..] > klasy/struktury a jesli ja zna to na tym etapie w formie meta > programowania np poprzez specjalizacje mozna by iterowac po skaldowych. > > Podobnie z enum podczas kompialcji zna calosc wyliczen wiec i nie > istnieje powod dla ktorego w formie metaprogramwoania/specjalizacji > klasy iteracji nie moglby udostepnic nazw wyliczen. >> Szkoda wielka. > a do czego taka compile-time'owa refleksja mialabybyc wykorzystywana? kto mialby tego uzywac - tworca kompilatora? zgoda ze 'musi to byc mozliwe' ale do czego fajnego mozna tego uzyc? fir |
|
#8
|
|
|
|
|
profesor_kinbote pisze:
>> Poprzez Compile Time Reflection rozumie prymitywne przeiterowanie >> skladowymi obiektow w formie metaprogramowania. To musi byc mozliwe >> dlatego ze do kompilacji wymagana jest definicja obiektow i musza byc >> znane rozmiary i musza byc znae offsety skladowych obiektu. Co wazne nie >> jest potrzebna implementacja a jak napisalem definicja typu >> klasy/struktury. Kompilator aby skompilowac kod musi znac definicje >> klasy/struktury a jesli ja zna to na tym etapie w formie meta >> programowania np poprzez specjalizacje mozna by iterowac po skaldowych. Chyba raz w życiu robiłem przez makro, z użyciem ##, coś w rodzaju class Przyklad {... ZMIENNA(double,wysokosc); ZMIENNA(char[10],nazwa); }... taki poziom C z klasami. C++ był zadowolony, a ja mialem swoją buchalterię (rejestrowanie w kolekcji itd). Ale to nie jest język do tego. Tu się nie zgodze co do wspolnego przodka. Ew wspolny przodek jest fajnym (zgodze sie: byc moze nie koniecznym) miejscem na takie 'sluzebne' sprawy (dodajmy: zliczanie referencji itd). Oczywiście moja mysl mi poszla na Runtime. >> >> Podobnie z enum podczas kompialcji zna calosc wyliczen wiec i nie >> istnieje powod dla ktorego w formie metaprogramwoania/specjalizacji >> klasy iteracji nie moglby udostepnic nazw wyliczen. > a do czego taka compile-time'owa refleksja mialabybyc wykorzystywana? Akurat bardzo życiowe spojrzenie. Niemozność 'naturalnego' wypisania enuma jest upierdliwa. Iterowanie po składowych, choćby w kierunku automatycznej prezentacji obiektu (a i nawet edycji), jest całkiem życiowe. Dlatego nie ma projektów w rodzaju Hibernate, Velocity i innych. Za czasów starego Fortranu dzieliliśmy na koniec 1/0 i porzadnie drukowała się zawartosc zmiennych (post mortem, debug info, zmienne jak byśmy dzis powiedzieli statyczne/extern). Oszczedzalo wiele linii programowania. |
|
#9
|
|
|
|
|
W dniu 2010-03-03 10:53, profesor_kinbote pisze:
> a do czego taka compile-time'owa refleksja mialabybyc wykorzystywana? > kto mialby tego uzywac - tworca kompilatora? zgoda ze 'musi to byc mozliwe' > ale do czego fajnego mozna tego uzyc? Majac mozliwosc iteracji po skladowych uzywajc metaprogramowania mozna np dokonywac autoamtycznej serializacji obiektow bez pisania metod odczytu i zapisu dla kazdego typu z pelna kontrola sposobu serialziacji skladowej w zaleznosci od typu. To świetnie widac na przykladzie co oferuje standard MPI C MPI_TYPE_STRUCT gdzie trzeba z reki okreslac skaldowe i adresy i poslugiwac sie pseudo identyfikatorem typu vs to co dostepne jest w implementacji wrapera dla C# gdzie pisze tylko Przyklad w C# [serializable] struct INDATA_TYPE { float a; float b; int n; }; INDATA_TYPE indata = new INDATA_TYPE(); MPI.Broadcast<INDATA_TYPE>( ref indata, root ); Przyklad w C zlenistwa wziolem gotowiec ze strony http://muflon.photosite.pl/doc/seminar/mpi/mpi.html : ------------------- typedef struct { float a; float b; int n; } INDATA_TYPE; .... MPI_Datatype *message_type_ptr; /* Wskaźnik do struktury typu */ int block_lengths[3]; /* Długości bloków (tu równe 1) */ MPI_Aint displacements[3]; /* Długości pól */ MPI_Aint addresses[4]; /* Adresy pól */ MPI_Datatype typelist[3]; /* Typy pojedynczych pól */ INDATA_TYPE indata; .... typelist[0]=MPI_FLOAT; /* Wypełniamy listę typów */ typelist[1]=MPI_FLOAT; typelist[2]=MPI_INT; /* W tym przykładzie wszystkie pola są pojedyncze */ block_lengths[0]=block_lengths[1]=block_lengths[2]=1; /* Ustalamy adresy pól */ MPI_Address(indata, &adresses[0]); MPI_Address(&(indata->a), &adresses[1]); MPI_Address(&(indata->b), &adresses[2]); MPI_Address(&(indata->n), &adresses[3]); /* Obliczamy przesunięcia */ displacements[0]=addresses[1]-addresses[0]; displacements[1]=addresses[2]-addresses[1]; displacements[2]=addresses[3]-addresses[2]; /* Tworzymy typ i rejestrujemy go w MPI */ MPI_Type_struct(3, block_lengths, displacements, typelist, message_type_ptr); MPI_Type_commit(message_type_ptr); .... /* Nowego typu możemy używać tak jak innych wbudowanych */ MPI_Bcast(indata, count, *message_type_ptr, root, MPI_COMM_WORLD); |
|
#10
|
|
|
|
|
On Mar 3, 2:13 pm, arturbac <artur_no_spam>
wrote: [..] > float a; > float b; > int n; > > }; > > INDATA_TYPE indata = new INDATA_TYPE(); > MPI.Broadcast<INDATA_TYPE>( ref indata, root ); > > Przyklad w C zlenistwa wziolem gotowiec ze stronyhttp://muflon.photosite.pl/doc/seminar/mpi/mpi.html: Ale w C++ można użyć boost MPI i boost serialization, nie będzie to takie proste i krótkie jak w C#, ale też nie będzie takie straszne jak ten przykład w C. Prawda jest taka, że na troche mneij banalnym przykładzie w C# będzie widać, że konieczne jest użycie refleksji runtime, bo korzystasz z serializacji, która obsługuje referencje, które mogą w szczególności być polimorficzne. Ale też prawda, że na początek wydaje się, że proste elementy refleksji compile-time powinno się dać prosto dodać do C++, największy chyba problem to konieczność zarezerwowania nowych słów kluczowych.:) I takie coś by było fajne, bo by znacząco uprościło właśnie rzeczy typu serializacja wszystkich memberów. Czy to się stanie, trudno powiedzieć, ale można chyba bezpiecznie założyć, że nie znajdzie się w standardzie w tej dekadzie. ;) |
|
#11
|
|
|
|
|
W dniu 2010-03-03 18:26, Andrzej Jarzabek pisze:
> Ale w C++ można użyć boost MPI i boost serialization, nie będzie to > takie proste i krótkie jak w C#, ale też nie będzie takie straszne jak > ten przykład w C. Boost odpada, jest nie akcpetowalny ale to dobre zrodlo do koncepcji rozwiazan prblemow. > Prawda jest taka, że na troche mneij banalnym przykładzie w C# będzie > widać, że konieczne jest użycie refleksji runtime, bo korzystasz z > serializacji, która obsługuje referencje, które mogą w szczególności > być polimorficzne. W wiekszosci zastosowan wystarczy ograniczony model dla typow nie polimorficznych, rozmawiamy o metodze metaprogramowania wiec bedziemy przetwarzac jak statyczne dla danego typu podanego jako argument specjalizacji. Takie jest z gory ograniczenie , to nie wyklucza stosowania statycznego polimorfizmu etapu kompilacji. Model runtime to inna bajka choc i ten powinien byc wykonalny dla typow polimorficznych skoro informacja o typie i kazdym typie skladowym bazowym i jego przesunieciu w obiekcie jest dostepna w obecnych kompialtorach vide moja implementacja dynamic_cast<> , oraz to co wygrzebalem w msvc dla evc4, http://code.google.com/p/wceccrtrtti...namic_cast.cpp http://code.google.com/p/wceccrtrtti...tti/ccrtrtti.h void * __cdecl __RTDynamicCast ( oraz template<typename __compare> static void * __rt_dynamic_cast_iterator( wiem ze mozna przeiterowac po wszystkich typach bazowych juz obecnie, wystarczy dodac inforamcje o skaldowych niepolimorficznych do wygenerowanego kodu aby moc iterowac po skaldowych. > Ale też prawda, że na początek wydaje się, że proste elementy > refleksji compile-time powinno się dać prosto dodać do C++, największy > chyba problem to konieczność zarezerwowania nowych słów kluczowych. :) Podejrzewam ze slowa kluczowe + troche roboty w zapisaniu inforamcji do kodu przez kompialtor. > I takie coś by było fajne, bo by znacząco uprościło właśnie rzeczy > typu serializacja wszystkich memberów. lub wybranych, bardzo fajny jest mechanizm z .NET (C#, C++CLI )atrybutow skladowych klas uzywajac ktorego mozna dodatkowo okreslic czy cos ma w czyms brac udzial czy nie. > Czy to się stanie, trudno powiedzieć, ale można chyba bezpiecznie > założyć, że nie znajdzie się w standardzie w tej dekadzie. ;) No i to jest smutne, "pierdoly" w stylu Lambda - nowego jezyka w jezyku wstawia sie do kodu a tak prostej funkcjonalnosci nie ;-) |
|
#12
|
|
|
|
|
On 3 Mar, 18:26, Andrzej Jarzabek <andrzejjarza> wrote:
> Ale w C++ można użyć boost MPI i boost serialization, nie będzie to > takie proste i krótkie jak w C#, ale też nie będzie takie straszne jak > ten przykład w C. (IMHO, etc.) Dużo lepszym pomysłem jest wyjście poza język. Nie da się sensownie rozwiązać żadnego problemu przy pomocy tych samych metod, które ten problem stworzyły. Myślę o czymś w rodzaju IDL albo typegen - zamiast męczyć się z makrami albo szablonami (bo nie oszukujmy się, ale to nie jest lekka robota), lepiej jest stworzyć odpowiedni DSL, który z jednej strony pozwoli na opis problemu w czytelnej postaci a z drugiej zadba (generacja kodu) o odpowiedni interfejs już na poziomie języka. Jakieś wady tego podejścia? |
|
#13
|
|
|
|
|
W dniu 2010-03-03 22:20, Maciej Sobczak pisze:
> On 3 Mar, 18:26, Andrzej Jarzabek <andrzejjarza> wrote: >> (IMHO, etc.) Dużo lepszym pomysłem jest wyjście poza język. Nie da > się sensownie rozwiązać żadnego problemu przy pomocy tych samych > metod, które ten problem stworzyły. > > Myślę o czymś w rodzaju IDL albo typegen - zamiast męczyć się z > makrami albo szablonami (bo nie oszukujmy się, ale to nie jest lekka > robota), lepiej jest stworzyć odpowiedni DSL, który z jednej strony > pozwoli na opis problemu w czytelnej postaci a z drugiej zadba > (generacja kodu) o odpowiedni interfejs już na poziomie języka. > Jakieś wady tego podejścia? Nie uzywam takich podejsc, nie akceptuje dodatkowych problemow wynikajacych z dodatkowych narzedzi do generacji kodu, to kompilkuje projekt, sa ciezko przenosne i ciezko automatyzowane. |
|
#14
|
|
|
|
|
arturbac pisze:
> W dniu 2010-03-03 22:20, Maciej Sobczak pisze: > > Nie uzywam takich podejsc, nie akceptuje dodatkowych problemow > wynikajacych z dodatkowych narzedzi do generacji kodu, to kompilkuje > projekt, sa ciezko przenosne i ciezko automatyzowane. Moje patrzenie na C/C++ doszło do pewnego punktu, że nie jest to często optymalny język do rozwiązań "aplikacyjnych" (zakodowany wprost), ale dobry do zrobienia frameworków do takich rozwiązań. Jeśli da to lepsze rozwiązanie ... (z zewn generatorów tego nie uzywałem ,ale Antlr i dał się zautomatyzować) |
|
#15
|
|
|
|
|
On 4 Mar, 00:25, arturbac <artur_no_spam>
wrote: > > Myślę o czymś w rodzaju IDL albo typegen > > Jakieś wady tego podejścia? > > Nie uzywam takich podejsc, nie akceptuje dodatkowych problemow > wynikajacych z dodatkowych narzedzi do generacji kodu, to kompilkuje > projekt, sa ciezko przenosne i ciezko automatyzowane. Jakie problemy wynikają z dodatkowych narzędzi do generacji kodu? W jakim stopniu taki projekt jest bardziej skomplikowany, niż projekt z makrami opisującymi struktury danych albo z piramidami szablonów? W jakim stopniu jest nieprzenośny skrypt w byleczym? OK, trzeba mieć interpreter. Na czym polega problem automatyzacji? Pre-build step w IDE lub dodatkowy target w Makefile'u tego problemu nie rozwiązują? Chciałbym taki tool napisać i chętnie poznam opinie na ten temat. Zalety z mojego punktu widzenia: - czytelność opisu w DSL, bo pierwotny język nie stanowi przeszkody na poziomie składni - można nawet zrobić DSL graficzny - naturalność interfejsu w wygenerowanym kodzie, bo kod można wygenerować dowolnie - szybkość kompilacji projektu, bo nie ma potrzeby męczyć kompilatora piramidalnymi szablonami - przenośność pomiędzy kompilatorami, z tego samego powodu - brak ograniczeń w rozszerzaniu procesu - np. oprócz generowania kodu można też generować dokumentację, w dowolnym formacie (stawiam szampana jak ktoś zrobi generowanie PDFa szablonami) |
|
|
|
|
| Podobne wątki | |
| Dla ambitnych :-) - reflection Cześć, Mam następujące pytanie: Czy można jakoś uzyskać typ przekazanego do metody parametru ? Konkretnie: Class getObjectClass(Object cokolwiek){ //działa dopóki... |
|
| Reflection i ClassLoader chcialem miec mozliwosc reflektowania dowolnej klasy wybranej przez fileChoosera ktora zapewne nie jest zaladowana do pamieci. ( plik *.class badz *.java ) ... jak moge tego... |
|
| Reflection w C++ Cześć Czy ktoś może wie, czy w C++ planowane jest wprowadzenie mechanizmu podobnego do mechanizmu reflection znanego z Java (reflection lub odzwierciedlenia lub... |
|
| Reflection api Witam! Dwa pytania zwiazane z reflection api. 1) czy da sie stale pola klasy (static final) zainicjowac przez reflection api? W static{} wpisuje odpowiedni kod - ale... |
|
|
Czasy w strefie GMT. Teraz jest 23:10. | Privacy Policy
|