Czy sizeof podaje dobra wielkosc typu?
Zauwazylem ze nie bardzo. Oto przyklad(BCB 3).
tworze strukture:
struct A{
__int16 x;
long y;
A t;
i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc jest....6!!
Moze mi ktos rozwiklac ta zagadke??
tworze strukture:
struct A{
__int16 x;
long y;
};
potem objekt
A t;
i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc
jest....6!!
Moze mi ktos rozwiklac ta zagadke??
np.w watcomie jest dyrektywa
#pragma pack(nn)
nn - żądana wielokrotność (np 1 i wszystko jest tak jak sobie policzysz)
hej
patka
P.S. Powinna istniec opcja kompilatora, ktora wylacza wyrownywanie.
tworze strukture:
struct A{
__int16 x;
long y;
};
potem objekt
A t;
i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc jest....6!!
Moze mi ktos rozwiklac ta zagadke??
Struktura nie musi miec dokladnie rozmiaru sumy swoich skladowych,
dochodzi czesto cos takiego jak wyrownanie - dorzucane sa dodatkowe
bajty aby odpowiednio ustawic adresy (rozmiary) skladowych (w tym
przypadku
nastepuje wyrownanie do 4 bajt-ow - magiczne 32 bity:). Dane zajmuja
wtedy troche wiecej miejsca, ale dostep do nich jest szybszy.
P.S. Powinna istniec opcja kompilatora, ktora wylacza wyrownywanie.
| Struktura nie musi miec dokladnie rozmiaru sumy swoich skladowych,
| dochodzi czesto cos takiego jak wyrownanie - dorzucane sa dodatkowe
| bajty aby odpowiednio ustawic adresy (rozmiary) skladowych (w tym
| przypadku
| nastepuje wyrownanie do 4 bajt-ow - magiczne 32 bity:). Dane zajmuja
| wtedy troche wiecej miejsca, ale dostep do nich jest szybszy.
| P.S. Powinna istniec opcja kompilatora, ktora wylacza wyrownywanie.
Istnieje "Data aligment" i mam ja standardowo ustawiona na "Double Word",
czyli 4 bajty, ale jest jeden problem. Gdy zmieniam ja na np. Word i
wszystkow przekompiluje, to dostaje bledy typu "Acces violination at addess
......" w bibliotece vcl35.bpl. Czy mozna cos z tym zrobic?
pozdrowienia
patka
tworze strukture:
struct A{
__int16 x;
long y;
};
potem objekt
A t;
i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
jak mu dam takie wyrazenie sizeof(__in16)+sizeof(long) to wratosc
jest....6!!
Moze mi ktos rozwiklac ta zagadke??
--
Milo
ICQ: 14939954
Z pozdrowieniem Jacek Korzewski
| Struktura nie musi miec dokladnie rozmiaru sumy swoich skladowych,
| dochodzi czesto cos takiego jak wyrownanie - dorzucane sa dodatkowe
| bajty aby odpowiednio ustawic adresy (rozmiary) skladowych (w tym
| przypadku
| nastepuje wyrownanie do 4 bajt-ow - magiczne 32 bity:). Dane zajmuja
| wtedy troche wiecej miejsca, ale dostep do nich jest szybszy.
| P.S. Powinna istniec opcja kompilatora, ktora wylacza wyrownywanie.
Istnieje "Data aligment" i mam ja standardowo ustawiona na "Double Word",
czyli 4 bajty, ale jest jeden problem. Gdy zmieniam ja na np. Word i
wszystkow przekompiluje, to dostaje bledy typu "Acces violination at
addess
......" w bibliotece vcl35.bpl. Czy mozna cos z tym zrobic?
Rozmiar struktury jest mi potzrebny do odczytu z pliku.
#pragma pack(push, 1)
definicja struktury
#pragma pack (pop)
aha, to jest Watcom 11, ale może w innych tez działa
[...]
Prawie wszyscy dali radę, żeby przełączyć opcję jakiegoś kompilatora,
coby pakował struktury ciaśniej.
Tymczasem moja rada: nic takiego nie robić, nie przejmować się,
tak ma być. Język C ani C++ nie gwarantuje konkretnego rozłożenia
elementów struktur i już.
I tak nie uzyskamy np. przenośności przez pakowanie struktur: po
pierwsze opcja pakowania, o ile w ogóle istnieje, jest prywatnym
rozszerzeniem konkretnego kompilatora, po drugie wielkości typów
całkowitych w różnych kompilatorach są różne, o jeszcze większych
różnicach między architekturami (endianness) nie wspominając.
Kompilatory dają "puste" miejsca w strukturach nie bez powodu, nie
należy ich poprawiać, chyba że wiemy co robimy.
#pragma pack(push, 1)
definicja struktury
#pragma pack (pop)
[...]
| i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
[...]
Prawie wszyscy dali radę, żeby przełączyć opcję jakiegoś kompilatora,
coby pakował struktury ciaśniej.
Tymczasem moja rada: nic takiego nie robić, nie przejmować się,
tak ma być. Język C ani C++ nie gwarantuje konkretnego rozłożenia
elementów struktur i już.
I tak nie uzyskamy np. przenośności przez pakowanie struktur: po
pierwsze opcja pakowania, o ile w ogóle istnieje, jest prywatnym
rozszerzeniem konkretnego kompilatora, po drugie wielkości typów
całkowitych w różnych kompilatorach są różne, o jeszcze większych
różnicach między architekturami (endianness) nie wspominając.
Kompilatory dają "puste" miejsca w strukturach nie bez powodu, nie
należy ich poprawiać, chyba że wiemy co robimy.
Istnieje "Data aligment" i mam ja standardowo ustawiona na "Double Word",
czyli 4 bajty, ale jest jeden problem. Gdy zmieniam ja na np. Word i
wszystkow przekompiluje, to dostaje bledy typu "Acces violination at addess
......" w bibliotece vcl35.bpl. Czy mozna cos z tym zrobic?
Rozmiar struktury jest mi potzrebny do odczytu z pliku.
Problem pojawia sie, gdy masz struktury, ktore sluza do komunikacji
z zewnetrznymi bibliotekami. Tych nie mozesz 'poprawiac'.
Czesto nie mozna, wiec tak po prostu zmieniac globalnej opcji.
Pozostaja pragmy, byc moze:
#pragma push
#pragma pack(1)
... tu struktura, ktora musi byc wyrownywana do jednego bajtu ...
#pragma pop
czy jakos tak.
| [...]
| i teraz sizeof(t) ma warotsc (wg. debuggera) 8!!!
| [...]
| Prawie wszyscy dali radę, żeby przełączyć opcję jakiegoś kompilatora,
| coby pakował struktury ciaśniej.
| Tymczasem moja rada: nic takiego nie robić, nie przejmować się,
| tak ma być. Język C ani C++ nie gwarantuje konkretnego rozłożenia
| elementów struktur i już.
| I tak nie uzyskamy np. przenośności przez pakowanie struktur: po
| pierwsze opcja pakowania, o ile w ogóle istnieje, jest prywatnym
| rozszerzeniem konkretnego kompilatora, po drugie wielkości typów
| całkowitych w różnych kompilatorach są różne, o jeszcze większych
| różnicach między architekturami (endianness) nie wspominając.
| Kompilatory dają "puste" miejsca w strukturach nie bez powodu, nie
| należy ich poprawiać, chyba że wiemy co robimy.
Mi to bylo bardzo potrzebne(przenosilem program z 16 bit na 32bit, wiec
zmienil sie rozmiar sytruktur i tym samym sposob ich odczytu z dysku co
jest
nieporzadane). Musialem poza tym uzyc typu __int16 zamiast int, bo ten
drugi
okazuje sie, ze ma wielkosc 4 bajtow, czyli tyle co long(ciekawa jaki
jest
teraz sens uzywania int'a).
struct moja_struktura
{
int pole1;
long pole2;
void zrob_dane_plikowe ( moja_struktura * z, dane_plikowe * do )
{
do-dane[0] = z-pole1 % 256;
do-dane[1] = z-pole1 / 256;
do-dane[2] = z-pole2 % 256;
do-dane[3] = z-pole2 / 256;
do-dane[4] = z-pole2 / 65536;
do-dane[5] = z-pole2 / (65536*256);
Jeśli nie ma powodu, żeby używać innego typu całkowitego, używa się
inta. int z założenia jest naturalnej wielkości dla danego środowiska.
Jeśli kompilator wykorzystuje 32bitowe rejestry, to int będzie pewnie
32bitowy. A jeśli procesor może liczyć na 64 bitach, to long może
mieć 64 bity...