الشبكة العربية لمطوري الألعاب

خبير مدير وسام البهنسي مشاركة 1

مرحباً، قمت بتصميم struct خاص بهدف أن يكون حجمه 6 بايتات. ولكن المترجم يصر أن حجمه 8 بايتات... هذا هو الكود:
struct DET
{
	WORD wSamState : 8;
	WORD wSamStage : 7;
	WORD wSamSampler : 1;				
};
union ST
{
	WORD wRenState;
	DET det;
};
struct STATE
{
	ST st;
	DWORD dwValue;
};

المترجم يعطيني هذه النتائج:
sizeof(DET) = 2
sizeof(ST) = 2
sizeof(STATE) = 8


ما المشكلة؟ المفروض أن حجم STATE يكون 6 بايتات (4+2 يساوي 6 أليس كذلك؟)...

وسام البهنسي
مبرمج في إنفيديا وإنفريمز

محترف مشرف عبد اللطيف حاجي علي مشاركة 2

و لمَ التعقيد؟ لماذا لا تقول فقط:
المترجم يدّعي أن حجم الـ structure التالي 8 مع أن حجمه 6:

struct STATE
{
	WORD wValue;
	DWORD dwValue;
};


أعتقد أنك استنتجت أن الحالة لا علاقة لها بالتركيبة العجيبة التي اخترعتها... هذا فقط "حشو" (padding) ... أي أن المترجم يضيف بعض البايتات لكي يصبح حجم الـ structure موافقاً لنوع المعالج و نظام التشغبل (16-Bit أو 32-Bit أو حتى 64-Bit)

عبد اللطيف حاجي علي
مبرمج
In|Framez

خبير مدير وسام البهنسي مشاركة 3

ولكن هذا الكلام غير معقول... إذا كنت أعتمد على حجز مصفوفة من هذا الـ struct لحفظها لاحقاً مثلاً، أو التعامل معها عن طريق حسابات pointer متقدمة تفترض الـ tight packing فنحن في مشكلة حقيقة الآن...

ألا يوجد طريقة لأجبر هذا الشيء على الانصياع لطلبي؟

وسام البهنسي
مبرمج في إنفيديا وإنفريمز

محترف مشرف عبد اللطيف حاجي علي مشاركة 4

أعتقد أن حالة حفظ المصفوفات محلولة ,فأنت حين تحفظ مصفوفة من الـ structures فإنك تستخدم sizeof(array) أو sizeof(STATE)*n و في الحالتين سيكون الحشو محسوباً (أي أنك ستكتب 2-Bytes إضافية لكل structure بقيم الله أعلم بها لتقرأها من جدبد عند قراءة الملف), أما بالنسبة للـ tight packing فإنني أقسمت منذ زمن ألا أتكلم في أشياء لا أعلم بها...
بالطبع يمكنك إجبار sizeof على العودة بالقيم المتوقعة (من قٍبلك على الأقل) و إن كنت لا أفضل هذه الطريقة:

#pragma pack(2)

struct Struct6
{
	WORD w;
	DWORD dw;
};

#pragma pack()

struct Struct8
{
	WORD w;
	DWORD dw;
};


كما هو واضح فإن حجم Struct6 سيكون 6 بايتات (لأن الـ padding صار الآن على مستوى 2-Bytes لا 4) ، بينما حجم Struct8 سيكون 8... يمكنك التعرف أكثر على هذه الطريقة و مُلابساتها من خلال:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/pragm_22.asp

عبد اللطيف حاجي علي
مبرمج
In|Framez

خبير مدير وسام البهنسي مشاركة 5

شكراً على تعليمة الـ pragma pack#. لقد حلت لي الأزمة...

وسام البهنسي
مبرمج في إنفيديا وإنفريمز

خبير  Mohammad Khashashneh مشاركة 6

I too never knew about this method. Thanks

من سار على الدرب وصل, من جد وجد...
بس عتبك على اللي بيسمع