eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programming › Pakowanie struktur
Ilość wypowiedzi w tym wątku: 65

  • 11. Data: 2015-12-03 15:05:04
    Temat: Re: Pakowanie struktur
    Od: Tomasz Kaczanowski <kaczus@dowyciecia_poczta.onet.pl>

    W dniu 2015-12-03 15:00, M.M. pisze:
    > On Thursday, December 3, 2015 at 2:34:00 PM UTC+1, Tomasz Kaczanowski wrote:
    >> W dniu 2015-12-03 14:08, M.M. pisze:
    >>> On Thursday, December 3, 2015 at 1:09:14 PM UTC+1, Tomasz Kaczanowski wrote:
    >>>
    >>>> i gdzieniegdzie będzie mały bum, bo *((int*)(buf+2)); może mieć zdziebko
    >>>> inną zawartość, niż nam się wydaje,
    >>>
    >>> Nie rozumiem. W jakich sytuacjach może mieć inną zawartość? Na moje
    >>> albo reprezentacja bitowa się zgadza, albo nie. Jeśli nie, to w
    >>> ogóle nie można używać kopiowania bitów.
    >>
    >> Tam gdzie zmienne muszą mieć wyrównane adresy. O ile w przypadku
    >> spakowanej struktury przy odczycie kompilator wykona za nas odpowiednie
    >> operacje, to w takim przypadku, gdy rzutujesz dane spod adresu, mówisz
    >> kompilatorowi "wiem co robię, nie wtrącaj się", a, że wynik może w takim
    >> przypadku być inny, cóż...
    >
    > To przy operacji:
    > *((int*)(buf+2))
    > kompilator nie wygeneruje takiego samego kodu jak przy wypakowaniu
    > inta przesuniętego o 2 bajty w strukturze? Myślałem że na danej
    > platformie kompilator bezpiecznie przerzuci dane na wyrównany adres i
    > dopiero potem zacznie operować na tych danych.


    z doświadczenia wiem, że nie poprawne było dopiero

    int zmienna;
    memcpy(zmienna, (buf+2), sizeof(int));


    --
    Kaczus
    http://kaczus.ppa.pl


  • 12. Data: 2015-12-03 15:20:26
    Temat: Re: Pakowanie struktur
    Od: Maciej Sobczak <s...@g...com>

    Piszę tutaj, ale problem dotyczy wszystkich postów w tym wątku.

    Uwaga 1: endianie atakują.

    Te tricki są do niczego i powinny być (i są) zakazane. W szczególności *wszystkie*
    pokazane do tej pory przykłady są zakazane przez przemysłowe standardy kodowania -
    właśnie dlatego, że działają tylko przypadkiem i to w ściśle określonych warunkach,
    których to warunków nie widać w kodzie.

    Jak chcecie przepakowywać protokoły sieciowe, to ręcznie (uwaga 2: do operacji na
    bitach służą typy unsigned) a nie przez jakieś tam pragma packi czy inne pola bitowe.
    Dobrze napisany kod jest przenośny. I czytelny.

    --
    Maciej Sobczak * http://www.inspirel.com


  • 13. Data: 2015-12-03 16:08:39
    Temat: Re: Pakowanie struktur
    Od: "M.M." <m...@g...com>

    On Thursday, December 3, 2015 at 3:05:24 PM UTC+1, Tomasz Kaczanowski wrote:
    > W dniu 2015-12-03 15:00, M.M. pisze:
    > > On Thursday, December 3, 2015 at 2:34:00 PM UTC+1, Tomasz Kaczanowski wrote:
    > >> W dniu 2015-12-03 14:08, M.M. pisze:
    > >>> On Thursday, December 3, 2015 at 1:09:14 PM UTC+1, Tomasz Kaczanowski wrote:
    > >>>
    > >>>> i gdzieniegdzie będzie mały bum, bo *((int*)(buf+2)); może mieć zdziebko
    > >>>> inną zawartość, niż nam się wydaje,
    > >>>
    > >>> Nie rozumiem. W jakich sytuacjach może mieć inną zawartość? Na moje
    > >>> albo reprezentacja bitowa się zgadza, albo nie. Jeśli nie, to w
    > >>> ogóle nie można używać kopiowania bitów.
    > >>
    > >> Tam gdzie zmienne muszą mieć wyrównane adresy. O ile w przypadku
    > >> spakowanej struktury przy odczycie kompilator wykona za nas odpowiednie
    > >> operacje, to w takim przypadku, gdy rzutujesz dane spod adresu, mówisz
    > >> kompilatorowi "wiem co robię, nie wtrącaj się", a, że wynik może w takim
    > >> przypadku być inny, cóż...
    > >
    > > To przy operacji:
    > > *((int*)(buf+2))
    > > kompilator nie wygeneruje takiego samego kodu jak przy wypakowaniu
    > > inta przesuniętego o 2 bajty w strukturze? Myślałem że na danej
    > > platformie kompilator bezpiecznie przerzuci dane na wyrównany adres i
    > > dopiero potem zacznie operować na tych danych.
    >
    >
    > z doświadczenia wiem, że nie poprawne było dopiero
    >
    > int zmienna;
    > memcpy(zmienna, (buf+2), sizeof(int));


    Jeśli wcześniej było:
    memcpy( buf+2 , &zmienna , sizeof(int) );
    To też nie widzę zagrożenia. Rozmawiamy rzecz jasna o zgodnym formacie
    na poziomie bitów.


    Gdy ktoś upakował dane przy pomocy memcpy, a potem odzyskuje przez:
    *((int*)(buf+2))
    to obawiam się, że nie zawsze zadziała, o ile się nie mylę, to zadziała
    tylko na bigendian.


    Pozdrawiam


  • 14. Data: 2015-12-03 16:19:26
    Temat: Re: Pakowanie struktur
    Od: "M.M." <m...@g...com>

    On Thursday, December 3, 2015 at 3:20:27 PM UTC+1, Maciej Sobczak wrote:
    > Piszę tutaj, ale problem dotyczy wszystkich postów w tym wątku.
    >
    > Uwaga 1: endianie atakują.
    >
    > Te tricki są do niczego i powinny być (i są) zakazane.
    Jakie triki? W ogóle nie można rozpoznać na podstawie samych
    danych w jakim formacie są zakodowane. Rozmawiamy oczywiście o
    zgodnych formatach. Jeśli formaty są niezgodne, to trzeba napisać
    switch każdej pary (src,dst) formatów.


    > W szczególności *wszystkie* pokazane do tej pory przykłady są zakazane
    > przez przemysłowe standardy kodowania - właśnie dlatego, że działają tylko
    > przypadkiem i to w ściśle określonych warunkach, których to warunków nie
    > widać w kodzie.
    Działają zawsze na zgodnych formatach.


    > Jak chcecie przepakowywać protokoły sieciowe, to ręcznie (uwaga 2: do operacji na
    bitach służą typy unsigned) a nie przez jakieś tam pragma packi czy inne pola bitowe.
    Dobrze napisany kod jest przenośny. I czytelny.
    Gdy są zgodne formaty, to nie trzeba niczego przepakowywać. Wystarczy
    odczytać (w tej samej kolejności) i używać.

    Pozdrawiam


  • 15. Data: 2015-12-03 16:21:30
    Temat: Re: Pakowanie struktur
    Od: witek <w...@g...pl.invalid>

    M.M. wrote:
    > Generalnie wtedy kiedy chcemy oszczędzać pamięć


    to chyba ostatnie z zastosowań jak się już komuś bardzo nudzi.






  • 16. Data: 2015-12-03 16:23:35
    Temat: Re: Pakowanie struktur
    Od: "M.M." <m...@g...com>

    On Thursday, December 3, 2015 at 4:21:31 PM UTC+1, witek wrote:
    > M.M. wrote:
    > > Generalnie wtedy kiedy chcemy oszczędzać pamięć
    >
    >
    > to chyba ostatnie z zastosowań jak się już komuś bardzo nudzi.

    To co innego może zrobić ktoś, komu dane nie mieszczą się w
    pamięci?

    Pozdrawiam


  • 17. Data: 2015-12-03 17:29:01
    Temat: Re: Pakowanie struktur
    Od: Maciej Sobczak <s...@g...com>


    > Jakie triki? W ogóle nie można rozpoznać na podstawie samych
    > danych w jakim formacie są zakodowane.

    Przecież nikt nie każe rozpoznawać formatu na podstawie danych. O ile zrozumiałem
    nawiązanie do protokołów sieciowych, to format jest zwykle znany z góry.

    > Rozmawiamy oczywiście o
    > zgodnych formatach.

    Co to znaczy zgodnych formatach? Jest jeden format (zwykle znany) i trzeba go
    zdekodować na poszczególne pola (albo odwrotnie - spakować ze znanych wartości pól).
    Te triki z pragmą, polami bitowymi albo rzutowaniem wskaźników to są złe rozwiązania.

    --
    Maciej Sobczak * http://www.inspirel.com


  • 18. Data: 2015-12-03 17:45:14
    Temat: Re: Pakowanie struktur
    Od: witek <w...@g...pl.invalid>

    M.M. wrote:
    > On Thursday, December 3, 2015 at 4:21:31 PM UTC+1, witek wrote:
    >> M.M. wrote:
    >>> Generalnie wtedy kiedy chcemy oszczędzać pamięć
    >>
    >>
    >> to chyba ostatnie z zastosowań jak się już komuś bardzo nudzi.
    >
    > To co innego może zrobić ktoś, komu dane nie mieszczą się w
    > pamięci?
    >

    zmienic algorytm.
    po za tym w jaki sposob wielkosc danych ma sie do faktu do czego stosuje
    sie pragma pack?


  • 19. Data: 2015-12-03 17:56:00
    Temat: Re: Pakowanie struktur
    Od: "M.M." <m...@g...com>

    On Thursday, December 3, 2015 at 5:29:03 PM UTC+1, Maciej Sobczak wrote:
    > > Jakie triki? W ogóle nie można rozpoznać na podstawie samych
    > > danych w jakim formacie są zakodowane.
    >
    > Przecież nikt nie każe rozpoznawać formatu na podstawie danych. O ile zrozumiałem
    nawiązanie do protokołów sieciowych, to format jest zwykle znany z góry.
    Jeśli przyszły dane w formacie znanym na podstawie protokołu, to trzeba
    napisać konwersję zgodną z danym formatem. Rozmowa, w kontekście znanego
    protokołu, zarówno o kopiowaniu bit po bicie, jak i o kopiowaniu z
    użyciem operatora konwersji (int), nie ma sensu. Rozmawialiśmy o
    szczególikach, typu:
    1) można się przejechać na big/lit endian
    2) najpierw memcpy, potem operator rzutowania
    3) różny padding w strukturach
    4) różny rozmiar inta na różnych platformach lub wersjach programu.


    > > Rozmawiamy oczywiście o
    > > zgodnych formatach.
    >
    > Co to znaczy zgodnych formatach? Jest jeden format (zwykle znany) i trzeba go
    zdekodować na poszczególne pola (albo odwrotnie - spakować ze znanych wartości pól).
    Te triki z pragmą, polami bitowymi albo rzutowaniem wskaźników to są złe rozwiązania.

    Dlaczego złe? Jeśli ktoś wysyła tablicę struktur wyrównanych do 1 bajta, to
    sytuacja ma się odwrotnie niż pisałeś: Jedynie przez przypadek odczyt
    zadziała na strukturach wyrównanych do 4 bajtów. Dlatego są złe, że nie
    używa się przenośnych funkcji do wysłania i odebrania każdego pola? Owszem
    to drobna wada. Ale wyobraź sobie, że ktoś pisze program tylko na windows i
    tylko na x86, ma strutkurę z 20ma polami i zamiast napisać
    write( &strukt , sizeof(strukt) , file )
    pisze 20 razy:
    write( unwersalny_format_int( strukt.pole1 ) , uniwersalny_rozmiar_int( strukt.pole1
    ) , file );

    Zgodzę się, że kod z memcpy jest ryzykowny, ale po pierwsze ryzyko to pojawia
    się tylko w określonych sytuacjach, a aktywne unikanie tego ryzyka zajmuje
    czas. Zobacz jak łatwo rypnąć się po poprawce pól w strukturze.


    Pozdrawiam





  • 20. Data: 2015-12-03 18:02:17
    Temat: Re: Pakowanie struktur
    Od: "M.M." <m...@g...com>

    On Thursday, December 3, 2015 at 5:45:16 PM UTC+1, witek wrote:
    > M.M. wrote:
    > > On Thursday, December 3, 2015 at 4:21:31 PM UTC+1, witek wrote:
    > >> M.M. wrote:
    > >>> Generalnie wtedy kiedy chcemy oszczędzać pamięć
    > >>
    > >>
    > >> to chyba ostatnie z zastosowań jak się już komuś bardzo nudzi.
    > >
    > > To co innego może zrobić ktoś, komu dane nie mieszczą się w
    > > pamięci?
    > >
    >
    > zmienic algorytm.
    > po za tym w jaki sposob wielkosc danych ma sie do faktu do czego stosuje
    > sie pragma pack?

    #include <cstdio>

    struct X1 {
    int c;
    char a;
    };


    #pragma push
    #pragma pack(1)
    struct X2 {
    int c;
    char a;
    };
    #pragma pop


    int main(int argc, char *argv[])
    {
    static X1 x1[1000];
    static X2 x2[1000];

    printf("sizeof(x1)==%u\n" , (sizeof(x1) ) );
    printf("sizeof(x2)==%u\n" , (sizeof(x2) ) );

    return 0;
    }

    U mnie taki wynik:
    sizeof(x1)==8000
    sizeof(x2)==5000

    Pozdrawiam




strony : 1 . [ 2 ] . 3 ... 7


Szukaj w grupach

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: