hilpers


  hilpers > comp.lang.* > comp.lang.c

 #1  
02.03.2010, 15:23
arturbac
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  
03.03.2010, 07:44
profesor_kinbote
> 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  
03.03.2010, 08:01
Jacek Czerwinski
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  
03.03.2010, 08:15
Maciej Sobczak
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  
03.03.2010, 08:29
profesor_kinbote
>
> 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  
03.03.2010, 08:39
arturbac
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  
03.03.2010, 08:53
profesor_kinbote
> 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  
03.03.2010, 09:20
Jacek Czerwinski
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  
03.03.2010, 13:13
arturbac
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  
03.03.2010, 16:26
Andrzej Jarzabek
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  
03.03.2010, 18:44
arturbac
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  
03.03.2010, 20:20
Maciej Sobczak
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  
03.03.2010, 22:25
arturbac
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  
04.03.2010, 04:23
Jacek Czerwinski
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  
04.03.2010, 08:22
Maciej Sobczak
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