-
1. Data: 2015-12-02 17:02:17
Temat: Pakowanie struktur
Od: Borneq <b...@a...hidden.pl>
Jest #pragma pack(1) ale wtedy spakuje mi wszystkie struktury nie tylko
z mojego pliku .h ale wszystkich .c które to dołączą. Jak zrobić pragmę,
która przywraca pakowanie takie jak było?
Jest jeszcze ilość bitów po dwukropku jak :8, :16 czy :32 - kiedy się
stosuje?
-
2. Data: 2015-12-02 17:56:41
Temat: Re: Pakowanie struktur
Od: Wojciech Muła <w...@g...com>
On Wednesday, December 2, 2015 at 5:02:15 PM UTC+1, Borneq wrote:
> Jest #pragma pack(1) ale wtedy spakuje mi wszystkie struktury nie tylko
> z mojego pliku .h ale wszystkich .c które to dołączą. Jak zrobić pragmę,
> która przywraca pakowanie takie jak było?
> Jest jeszcze ilość bitów po dwukropku jak :8, :16 czy :32 - kiedy się
> stosuje?
https://pl.wikipedia.org/wiki/Struktura_%28programow
anie%29#Struktura_w_j.C4.99zyku_C
-
3. Data: 2015-12-02 18:21:15
Temat: Re: Pakowanie struktur
Od: "M.M." <m...@g...com>
On Wednesday, December 2, 2015 at 5:02:15 PM UTC+1, Borneq wrote:
> Jest jeszcze ilość bitów po dwukropku jak :8, :16 czy :32 - kiedy się
> stosuje?
Generalnie wtedy kiedy chcemy oszczędzać pamięć i przechowywać specyficzne
wartości, np. trzy liczby, każda zajmująca max 10 bitów. Bez tej sztuczki
potrzeba trzech typów 16-bitowych, czyli razem 48 bitów. Z tą sztuczką 30
bitów, które kompilator wyrówna do 32 - mamy oszczędność 16 bitów.
Pozdrawiam
-
4. Data: 2015-12-03 10:31:55
Temat: Re: Pakowanie struktur
Od: JDX <j...@o...pl>
On 2015-12-02 18:21, M.M. wrote:
> On Wednesday, December 2, 2015 at 5:02:15 PM UTC+1, Borneq wrote:
>> Jest jeszcze ilość bitów po dwukropku jak :8, :16 czy :32 - kiedy się
>> stosuje?
> Generalnie wtedy kiedy chcemy oszczędzać pamięć i przechowywać specyficzne
> wartości, np. trzy liczby, każda zajmująca max 10 bitów. Bez tej sztuczki
> potrzeba trzech typów 16-bitowych, czyli razem 48 bitów. Z tą sztuczką 30
> bitów, które kompilator wyrówna do 32 - mamy oszczędność 16 bitów.
Jesteś pewien, że wyrównywanie odbywa się na poziomie bitów a nie
bajtów? Bo zgodnie z tym co napisałeś, poniższy programik na i386
powinien wyświetlić "2 6 4", a nie wyświetla.
---------------------- Tnij tutaj --------------------------------
#include <stdio.h>
typedef struct {
short int a;
short int b;
short int c;
} my_struct;
typedef struct {
short int a:10;
short int b:10;
short int c:10;
} my_fancy_struct;
int main(int argc, char *argv[])
{
printf("%d\t%d\t%d\n", sizeof(short int), sizeof(my_struct),
sizeof(my_fancy_struct));
return 0;
}
---------------------- Tnij tutaj --------------------------------
Wynik:
D:\WorkDir>gcc --version
gcc (i686-win32-sjlj-rev0, Built by MinGW-W64 project) 5.2.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
D:\WorkDir>gcc -O3 -s -o struct_test.exe struct_test.c
D:\WorkDir>struct_test
2 6 6
D:\WorkDir>
-
5. Data: 2015-12-03 10:59:25
Temat: Re: Pakowanie struktur
Od: Adam Klobukowski <a...@g...com>
W dniu środa, 2 grudnia 2015 18:21:16 UTC+1 użytkownik M.M. napisał:
> On Wednesday, December 2, 2015 at 5:02:15 PM UTC+1, Borneq wrote:
> > Jest jeszcze ilość bitów po dwukropku jak :8, :16 czy :32 - kiedy się
> > stosuje?
> Generalnie wtedy kiedy chcemy oszczędzać pamięć i przechowywać specyficzne
> wartości, np. trzy liczby, każda zajmująca max 10 bitów. Bez tej sztuczki
> potrzeba trzech typów 16-bitowych, czyli razem 48 bitów. Z tą sztuczką 30
> bitów, które kompilator wyrówna do 32 - mamy oszczędność 16 bitów.
> Pozdrawiam
Nie tylko. To trzeba też robic przy dekodowaniu danych idących strumieniem.
Przykładowo: mamy system który ma domyslnie 4 bajty na inta i tak rozpisuje struktury
(pole short int w strukturze i tak bedzie mialo 4 bajty). Teraz, jeśli w takim
systemie przymiemey strumien danych, gdzie short int jest spakowany na 2 bajty, to po
zapisaniu takiego strumienia nie możemy go wprost intepretować 'normalna' strukturą,
ale własnie takie taką spakowaną, lub stosować ine sztuczki. Tego typu problemy
wystepują np. w implementacjach protokołów sieciowych.
AdamK
-
6. Data: 2015-12-03 12:55:48
Temat: Re: Pakowanie struktur
Od: "M.M." <m...@g...com>
On Thursday, December 3, 2015 at 10:59:27 AM UTC+1, Adam Klobukowski wrote:
> W dniu środa, 2 grudnia 2015 18:21:16 UTC+1 użytkownik M.M. napisał:
> > On Wednesday, December 2, 2015 at 5:02:15 PM UTC+1, Borneq wrote:
> > > Jest jeszcze ilość bitów po dwukropku jak :8, :16 czy :32 - kiedy się
> > > stosuje?
> > Generalnie wtedy kiedy chcemy oszczędzać pamięć i przechowywać specyficzne
> > wartości, np. trzy liczby, każda zajmująca max 10 bitów. Bez tej sztuczki
> > potrzeba trzech typów 16-bitowych, czyli razem 48 bitów. Z tą sztuczką 30
> > bitów, które kompilator wyrówna do 32 - mamy oszczędność 16 bitów.
> > Pozdrawiam
>
> Nie tylko. To trzeba też robic przy dekodowaniu danych idących strumieniem.
Przykładowo: mamy system który ma domyslnie 4 bajty na inta i tak rozpisuje struktury
(pole short int w strukturze i tak bedzie mialo 4 bajty). Teraz, jeśli w takim
systemie przymiemey strumien danych, gdzie short int jest spakowany na 2 bajty, to po
zapisaniu takiego strumienia nie możemy go wprost intepretować 'normalna' strukturą,
ale własnie takie taką spakowaną, lub stosować ine sztuczki. Tego typu problemy
wystepują np. w implementacjach protokołów sieciowych.
Jeśli dekodowanie chcemy zrobić przy pomocy memcpy lub przy pomocy
rzutowania wskaźników to owszem. Ale dekodowanie można też zrobić
do nieupakowanej struktury:
// przepraszam za metakod
char buf[2*6] = read();
struct X {
short a;
int b;
};
X x[2];
x[0].a = *((short*)(buf+0));
x[0].b = *((int*)(buf+2));
x[1].a = *((short*)(buf+6));
x[1].b = *((int*)(buf+8));
Pozdrawiam
-
7. Data: 2015-12-03 13:09:14
Temat: Re: Pakowanie struktur
Od: Tomasz Kaczanowski <kaczus@dowyciecia_poczta.onet.pl>
W dniu 2015-12-03 12:55, M.M. pisze:
> On Thursday, December 3, 2015 at 10:59:27 AM UTC+1, Adam Klobukowski wrote:
>> W dniu środa, 2 grudnia 2015 18:21:16 UTC+1 użytkownik M.M. napisał:
>>> On Wednesday, December 2, 2015 at 5:02:15 PM UTC+1, Borneq wrote:
>>>> Jest jeszcze ilość bitów po dwukropku jak :8, :16 czy :32 - kiedy się
>>>> stosuje?
>>> Generalnie wtedy kiedy chcemy oszczędzać pamięć i przechowywać specyficzne
>>> wartości, np. trzy liczby, każda zajmująca max 10 bitów. Bez tej sztuczki
>>> potrzeba trzech typów 16-bitowych, czyli razem 48 bitów. Z tą sztuczką 30
>>> bitów, które kompilator wyrówna do 32 - mamy oszczędność 16 bitów.
>>> Pozdrawiam
>>
>> Nie tylko. To trzeba też robic przy dekodowaniu danych idących strumieniem.
Przykładowo: mamy system który ma domyslnie 4 bajty na inta i tak rozpisuje struktury
(pole short int w strukturze i tak bedzie mialo 4 bajty). Teraz, jeśli w takim
systemie przymiemey strumien danych, gdzie short int jest spakowany na 2 bajty, to po
zapisaniu takiego strumienia nie możemy go wprost intepretować 'normalna' strukturą,
ale własnie takie taką spakowaną, lub stosować ine sztuczki. Tego typu problemy
wystepują np. w implementacjach protokołów sieciowych.
>
> Jeśli dekodowanie chcemy zrobić przy pomocy memcpy lub przy pomocy
> rzutowania wskaźników to owszem. Ale dekodowanie można też zrobić
> do nieupakowanej struktury:
>
> // przepraszam za metakod
> char buf[2*6] = read();
> struct X {
> short a;
> int b;
> };
>
> X x[2];
> x[0].a = *((short*)(buf+0));
> x[0].b = *((int*)(buf+2));
> x[1].a = *((short*)(buf+6));
> x[1].b = *((int*)(buf+8));
>
> Pozdrawiam
i gdzieniegdzie będzie mały bum, bo *((int*)(buf+2)); może mieć zdziebko
inną zawartość, niż nam się wydaje, ale co do tego, że dekodować można
nie zwracając uwagi na upakowanie to fakt...
--
Kaczus
http://kaczus.ppa.pl
-
8. Data: 2015-12-03 14:08:20
Temat: Re: Pakowanie struktur
Od: "M.M." <m...@g...com>
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.
Pozdrawiam
-
9. Data: 2015-12-03 14:33:59
Temat: Re: Pakowanie struktur
Od: Tomasz Kaczanowski <kaczus@dowyciecia_poczta.onet.pl>
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óż...
--
Kaczus
http://kaczus.ppa.pl
-
10. Data: 2015-12-03 15:00:13
Temat: Re: Pakowanie struktur
Od: "M.M." <m...@g...com>
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.
Pozdrawiam