#pragma pack

0

Hej,

dlaczego w poniższym kodzie otrzymuję wynik 3? Czemu nie działa/nie umiem korzystać z #pragma pack?

#include <iostream>
using namespace std;

#pragma pack(push, 4)
typedef struct _B
{
	char a, b, c;
} B;
#pragma pack(pop)

int main()
{
	cout << sizeof(B) << endl;
	return(0);
} 

Dzięki ;)

0

A jakiego wyniku się spodziewałeś? Masz 3 elementy o wielkości 1. Razem ich wielkość to 3. Alignment jest 1, więc nie ma paddingu.

edit: Chociaż teoretycznie użyłeś nazwy _B, wywołując UB (nazwa zarezerwowana dla implementacji), więc w sumie nie masz nawet gwarancji, że cokolwiek zostanie wyświetlone na ekranie.

0

Już pal licho z nazwą. Spodziewałem się 12, bo myślałem, że wyrówna chary co 4 bajty.

W takim razie dlaczego

struct Test
{
   char a;
   int b;
   char c;
}; 

Wyrównuje wszystko, tak jak się spodziewam, czyli do 12B, a z kolei:

struct Test
{
   char a;
   char intruz;
   int b;
   char c;
}; 

również daje mi 12B, dlaczego nie wyrównuje pomiędzy charami, a pomiędzy intami juz tak ?

0

Pomiędzy charem i intem* miało być zamiast pomiędzy intami

1
Zaniepokojony napisał(a):

nie umiem korzystać z #pragma pack?
Tak.

#include <iostream>
using namespace std;

#pragma pack(push)
#pragma pack(4)
typedef struct _B
  {
   char a, b, c;
  }B;
#pragma pack(pop)
 
int main()
  {
   cout << sizeof(_B) << endl;
   cout << sizeof(B) << endl;
   return(0);
  }

http://ideone.com/UZPsdh

0

Tak, ale pack nie zmienia alignmentu w górę, tylko w dół. (chociaż w sumie nie ma tego w dokumentacji, no ale proszę, to jest dość logiczne - wymyśl prawidłowy use-case dla większego alignmentu).

Jeśli chodzi o Twoje strukturki Test - int jest wyrównywany tam do 4 bajtów, char do 1, więc masz odpowiednio ułożenie

char 1bajt
padding 3 bajty
int 4 bajty
char 1bajt
padding 3 bajty

i

char 1bajt
char 1bajt
padding 2 bajty
int 4 bajty
char 1bajt
padding 3 bajty
0

http://ideone.com/EX0VAP

cały problem polega na tym, że nie rozumiesz jak to działa.
Chodzi o to, by dostęp był jak najszybszy. W przypadku małych obiektów to ie jest problem, bo zawsze odczytać i zapisać trzeba ten sam rozmiar pamięci. W przypadku większych obiektów chodzi o wyrównanie adresu, by dostęp do pamięci nie wymagał odczytu dwóch komórek pamięci.

Obecnie pamięć ram tak naprawdę nie jest adresowana z dokładnością bajta, ale 4 bajtów (lub nawet więcej), a kontroler pamięci pozwala widzieć procesorowi pojedyncze bajty. Więc wyrównanie int-a do równego adresu pozwala na optymalizację dostępu pamięci i jednego odczytu pamięci zamiast dwóch odczytów.
W przypadku char nie ma tego problemu, zawsze odczytujesz jedną komórkę, więc można je upakować bez straty na wydajności.

Disclaimer: jest to nieco bardziej skomplikowane (i pewnie coś pokręciłem), ale ogólny koncept.problem powinieneś zrozumieć.

1 użytkowników online, w tym zalogowanych: 0, gości: 1