I have a C++ program representing a TCP header as a struct:
#include 'stdafx.h' /* TCP HEADER 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Port | Destination Port | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Sequence Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Acknowledgment Number | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Data | |U|A|P|R|S|F| | | Offset| Reserved |R|C|S|S|Y|I| Window | | | |G|K|H|T|N|N| | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Checksum | Urgent Pointer | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | data | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ typedef struct { // RFC793 WORD wSourcePort; WORD wDestPort; DWORD dwSequence; DWORD dwAcknowledgment; unsigned int byReserved1:4; unsigned int byDataOffset:4; unsigned int fFIN:1; unsigned int fSYN:1; unsigned int fRST:1; unsigned int fPSH:1; unsigned int fACK:1; unsigned int fURG:1; unsigned int byReserved2:2; unsigned short wWindow; WORD wChecksum; WORD wUrgentPointer; } TCP_HEADER, *PTCP_HEADER; int _tmain(int argc, _TCHAR* argv[]) { printf('TCP header length: %d\n', sizeof(TCP_HEADER)); return 0; }
If I run this program I get the size of this header as 24 bytes, which is not the size I was expecting. If I change the type of the field ‘wWindow’ to ‘unsigned int wWindow:16’, which has the same number of bits as an unsigned short, the program tells me the size of the struct is now 20 bytes, the correct size. Why is this?
I am using Microsoft Visual Studio 2005 with SP1 on a 32-bit x86 machine.
See this question: Why isn't sizeof for a struct equal to the sum of sizeof of each member? .
I believe that compiler takes a hint to disable padding when you use the ‘unsigned int wWindow:16’ syntax.
Also, note that a short is not guaranteed to be 16 bits. The guarantee is that: 16 bits <= size of a short <= size of an int.