I have a struct that I wrote to test a protocol. The idea I had was
to just declare the elements of the struct in the order in which they
are sent and received as defined by the protocol. However, writing
this struct to a file produces unexpected results.
Here is a test struct I wrote:
struct Tester {
unsigned short first;
unsigned int second;
};
Checking the sizeof variables declared to be of this type, I get 64
bits, when really the size of a short is 16 bits, and the size of an
int is 32 bits. Declaring the struct to have two shorts produces
expected results, and declaring it to have one short also produces
expected results.
I do understand what is going on here. The size is being adjusted
or "aligned" (I don't want to misuse that term so correct me if I used
it wrong) to the size of the largest constituent element. However, I
would like to prevent this as it does have the end result of munging
communication as it relates to this protocol.
I originally discovered this in D, where I had a struct which
contained shorts, ints, and a long. I was able to reproduce it in C,
so I figure it's a more basic issue with a generic response
(hopefully).
What can I do to have a struct, declared as above, either return a
size of 6, or be manipulated so as to present itself as a string of 48
bits?
Thanks everyone, for your time. 10 2343
On 20 Aug 2004 09:40:53 -0700, se******@bluebeard.org (Sean) wrote: I have a struct that I wrote to test a protocol. The idea I had was to just declare the elements of the struct in the order in which they are sent and received as defined by the protocol. However, writing this struct to a file produces unexpected results.
Here is a test struct I wrote:
struct Tester { unsigned short first; unsigned int second; };
Checking the sizeof variables declared to be of this type, I get 64 bits, when really the size of a short is 16 bits, and the size of an int is 32 bits. Declaring the struct to have two shorts produces expected results, and declaring it to have one short also produces expected results.
I do understand what is going on here. The size is being adjusted or "aligned" (I don't want to misuse that term so correct me if I used it wrong) to the size of the largest constituent element. However, I would like to prevent this as it does have the end result of munging communication as it relates to this protocol.
I originally discovered this in D, where I had a struct which contained shorts, ints, and a long. I was able to reproduce it in C, so I figure it's a more basic issue with a generic response (hopefully).
What can I do to have a struct, declared as above, either return a size of 6, or be manipulated so as to present itself as a string of 48 bits?
Thanks everyone, for your time.
Depending upon your compiler you should investigate a method to allow
the structure to be packed.
With Gcc you may use __attribute__ ((packed)) for example.
Eg.
struct Tester {
unsigned short first;
unsigned int second;
} __attribute__ ((packed));
l8r
Sean wrote: Here is a test struct I wrote:
struct Tester { unsigned short first; unsigned int second; };
Checking the sizeof variables declared to be of this type, I get 64 bits, when really the size of a short is 16 bits, and the size of an int is 32 bits. Declaring the struct to have two shorts produces expected results, and declaring it to have one short also produces expected results.
Your compiler is padding the structure so that's its a multiple of 8 bytes.
The compiler is free to do this and usually it's to make optimizations
possible [and loads/stores quicker].
If you want exact sizes you'll have to use compiler specific ``attributes''
which are off topic here.
Tom
Sean wrote: I have a struct that I wrote to test a protocol. The idea I had was to just declare the elements of the struct in the order in which they are sent and received as defined by the protocol. However, writing this struct to a file produces unexpected results.
This is Question 2.12 in the comp.lang.c Frequently
Asked Questions (FAQ) list http://www.eskimo.com/~scs/C-faq/top.html
.... and you're not going to like the answer.
-- Er*********@sun.com
Sean <se******@bluebeard.org> wrote: I have a struct that I wrote to test a protocol. The idea I had was to just declare the elements of the struct in the order in which they are sent and received as defined by the protocol. However, writing this struct to a file produces unexpected results.
Here is a test struct I wrote:
struct Tester { unsigned short first; unsigned int second; };
Checking the sizeof variables declared to be of this type, I get 64 bits, when really the size of a short is 16 bits, and the size of an int is 32 bits. Declaring the struct to have two shorts produces expected results, and declaring it to have one short also produces expected results.
I do understand what is going on here. The size is being adjusted or "aligned" (I don't want to misuse that term so correct me if I used it wrong) to the size of the largest constituent element. However, I
No, its get aligned to whatever the compiler thinks is reasonable.
Part of the problem is that on some systems it's e.g. not allowed
to access integers that don't start on a address that can be divided
by 4. And when a short int has a size of 2 and there would be no
padding the int would start on an address that only can be divided
by 2 but not by 4 and an read or write access to that int would crash
the program.
would like to prevent this as it does have the end result of munging communication as it relates to this protocol.
What can I do to have a struct, declared as above, either return a size of 6, or be manipulated so as to present itself as a string of 48 bits?
Some compilers let you invoke some compiler-specific magic that
makes it leave out the padding for the structure - see your
compiler documentation for that. But there's no portable way to
do it.
If you want to stay portable use an array of unsigned chars, long
enough to hold the data, instead of a structure. Copy them into (or
out of) the array using memcpy() and finally write that array to
the file or read it back, i.e. something like this:
unsigned char buf[ sizeof( unsigned short ) + sizeof ( unsigned int ) ];
unsigned short first;
unsigned int second;
FILE *fp;
....
memcpy( buf, &first, sizeof first );
memcpy( buf + sizeof first, &second, sizeof second );
if ( fwrite( buf, sizeof buf, 1, fp ) != sizeof buf )
exit( EXIT_FAILURE );
....
if ( fread( buf, sizeof buf, 1, fp ) != sizeof buf )
exit( EXIT_FAILURE );
memcpy( &first, buf, sizeof first );
memcpy( &second, buf + sizeof first, sizeof second );
If this looks too ugly hide it away in a function;-)
Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Sean wrote: I have a struct that I wrote to test a protocol. The idea I had was to just declare the elements of the struct in the order in which they are sent and received as defined by the protocol. However, writing this struct to a file produces unexpected results.
Here is a test struct I wrote:
struct Tester { unsigned short first; unsigned int second; };
Checking the sizeof variables declared to be of this type, I get 64 bits,
How do you determine this? sizeof measures in char units, not bit units.
when really the size of a short is 16 bits,
You know this because...?
and the size of an int is 32 bits.
You know this because...?
Declaring the struct to have two shorts produces expected results, and declaring it to have one short also produces expected results.
I do understand what is going on here. The size is being adjusted or "aligned" (I don't want to misuse that term so correct me if I used it wrong) to the size of the largest constituent element.
No, not really.
The elements of your struct are individually aligned on boundaries that
your compiler has determined they must be aligned on. A hypothetical
example would be that
sizeof (short) is 2,
short elements must be aligned on a 2 char boundary,
sizeof (int) is 4, and
int elements must be aligned on a 4 char boundary,
meaning that
struct {
short n1;
int n2;
};
resulting in placement of n1 taking up 2 chars, and n2 not being
able to start at the next available char because it needs to be on
a 4 char boundary. The compiler would 'inject' some padding between
the short and the int so as to make the int fall on a 4 char boundary.
However,
struct {
int n2;
short n1;
};
would result in the placement of n2 taking up 4 chars, and n1 being
able to start on a 2 char boundary. In this case the compiler would
not have to inject padding.
However, I would like to prevent this as it does have the end result of munging communication as it relates to this protocol.
This is a compiler-dependant issue. You have to go back to your
compiler's documentation and find a way to tell it to use different
alignment rules. In some compilers, this can be a #pragma preprocessor
directive, while others will use a commandline option.
This is not a C issue.
[snip]
- --
Lew Pitcher, IT Consultant, Enterprise Application Architecture
Enterprise Technology Solutions, TD Bank Financial Group
(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)
iD8DBQFBJi4fagVFX4UWr64RAnQsAKCJpqzpHOC4CIW6L9Vq5M S8GmQlkgCeIA48
PsiyPVMAB/jXI2XZABRzS4E=
=38vT
-----END PGP SIGNATURE-----
On Fri, 20 Aug 2004 17:50:57 +0100, Mr Wibble <wi****@eurobell.co.uk>
wrote in comp.lang.c: On 20 Aug 2004 09:40:53 -0700, se******@bluebeard.org (Sean) wrote:
I have a struct that I wrote to test a protocol. The idea I had was to just declare the elements of the struct in the order in which they are sent and received as defined by the protocol. However, writing this struct to a file produces unexpected results.
Here is a test struct I wrote:
struct Tester { unsigned short first; unsigned int second; };
Checking the sizeof variables declared to be of this type, I get 64 bits, when really the size of a short is 16 bits, and the size of an int is 32 bits. Declaring the struct to have two shorts produces expected results, and declaring it to have one short also produces expected results.
I do understand what is going on here. The size is being adjusted or "aligned" (I don't want to misuse that term so correct me if I used it wrong) to the size of the largest constituent element. However, I would like to prevent this as it does have the end result of munging communication as it relates to this protocol.
I originally discovered this in D, where I had a struct which contained shorts, ints, and a long. I was able to reproduce it in C, so I figure it's a more basic issue with a generic response (hopefully).
What can I do to have a struct, declared as above, either return a size of 6, or be manipulated so as to present itself as a string of 48 bits?
Thanks everyone, for your time.
Depending upon your compiler you should investigate a method to allow the structure to be packed.
With Gcc you may use __attribute__ ((packed)) for example.
Eg.
struct Tester { unsigned short first; unsigned int second; } __attribute__ ((packed));
l8r
This is actually an extremely bad idea. On some platforms it will
only produce code that executes more slowly. On others, violating the
hardware alignment requirements will result in hardware exceptions
killing the program.
And it's off-topic here.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
"Sean" <se******@bluebeard.org> wrote in message
news:d5**************************@posting.google.c om... I have a struct that I wrote to test a protocol. The idea I had was to just declare the elements of the struct in the order in which they are sent and received as defined by the protocol. However, writing this struct to a file produces unexpected results.
Here is a test struct I wrote:
struct Tester { unsigned short first; unsigned int second; };
You could try reversing the order. By putting the int first it will be
aligned to whatever boundary it requires "outside" of the structure. Then
the short _may_ be able to skip the padding, if it is allowed to align right
behind the int. It's worth testing, just to know for future reference on
that compiler / platform.
--
Mabden
"Mabden" <mabden@sbc_global.net> wrote in message
news:F8*****************@newssvr29.news.prodigy.co m... "Sean" <se******@bluebeard.org> wrote in message news:d5**************************@posting.google.c om... I have a struct that I wrote to test a protocol. The idea I had was to just declare the elements of the struct in the order in which they are sent and received as defined by the protocol. However, writing this struct to a file produces unexpected results.
Here is a test struct I wrote:
struct Tester { unsigned short first; unsigned int second; };
You could try reversing the order. By putting the int first it will be aligned to whatever boundary it requires "outside" of the structure. Then the short _may_ be able to skip the padding, if it is allowed to align right behind the int.
On most implementations there will still be padding after the unsigned
short, and sizeof(struct Tester) will be unchanged.
Alex
"Alex Fraser" <me@privacy.net> wrote in message
news:2o************@uni-berlin.de... "Mabden" <mabden@sbc_global.net> wrote in message news:F8*****************@newssvr29.news.prodigy.co m... "Sean" <se******@bluebeard.org> wrote in message news:d5**************************@posting.google.c om... I have a struct that I wrote to test a protocol. The idea I had was to just declare the elements of the struct in the order in which they are sent and received as defined by the protocol. However, writing this struct to a file produces unexpected results.
Here is a test struct I wrote:
struct Tester { unsigned short first; unsigned int second; };
You could try reversing the order. By putting the int first it will be aligned to whatever boundary it requires "outside" of the structure.
Then the short _may_ be able to skip the padding, if it is allowed to align right behind the int.
On most implementations there will still be padding after the unsigned short, and sizeof(struct Tester) will be unchanged.
Of course. That is why I said to "try it" and it "may work", and in the part
you snipped, that "It's worth testing, just to know for future reference on
that compiler / platform."
But thanks for the useful insights you provided.
--
Mabden
Jack Klein <ja*******@spamcop.net> writes: On Fri, 20 Aug 2004 17:50:57 +0100, Mr Wibble <wi****@eurobell.co.uk> wrote in comp.lang.c:
[...] Depending upon your compiler you should investigate a method to allow the structure to be packed.
With Gcc you may use __attribute__ ((packed)) for example.
Eg.
struct Tester { unsigned short first; unsigned int second; } __attribute__ ((packed));
This is actually an extremely bad idea. On some platforms it will only produce code that executes more slowly. On others, violating the hardware alignment requirements will result in hardware exceptions killing the program.
Methods that allow packing structures are compiler-specific and
extremely non-portable (see question 2.12 in the C FAQ).
However, if a compiler does provide such a mechanism, it will almost
certainly do whatever is necessary to generate the right code to
access the members without killing the program. In the case of
"struct Tester" above, this might involve using two instructions to
access the halves of the (misaligned) member "second", or using the
equivalent of memcpy().
--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this. This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: ak |
last post by:
struct xy{
int x;
int y;
}
_xy;
size_of_xy(struct xy * a) {
int len = sizeof a;
printf( "\sizeof xy: %i\n", len );
}
|
by: Sean |
last post by:
I perused the archives of comp.lang.c and found some answers related
to addressability of struct elements (only in arrays?), and will
probably proceed by using byte or char arrays filled with raw...
|
by: aegis |
last post by:
sizeof could not possibly evaluate to some size for a type, unless
two things for a type occur:
a) the type is complete and sizeof will evaluate to appropriate size
b) type is not complete and...
|
by: JohnGoogle |
last post by:
Hi,
Newbie question...
After a recent article in VSJ I had a go at implementing a Fraction
class to aid my understanding of operator overloading. After a previous
message someone suggested...
|
by: Chameleon |
last post by:
I have a TGA image header struct.
TGA has 18 bytes header, so the C struct too.
why this return 20?
sizeof(TGAHeader)
I saw this in many structs. I believe compiler round up the size to 4...
|
by: Yevgen Muntyan |
last post by:
Consider the following macro:
#define ALLOCIT(Type) ((Type*) malloc (sizeof (Type)))
The intent is to wrap raw memory allocation of N bytes
into a macro which returns allocated chunk of memory...
|
by: goacross |
last post by:
char ch='a';
int v=sizeof ++ch;
cout<<ch<<endl;// output: 'a'
why not 'b'?
thanks
|
by: Boltar |
last post by:
Hi
Why - using gcc on linux - does this return 0 in C but returns 1 in C+
+? I don't get it.
#include <stdio.h>
struct foo
{
};
|
by: MTsoul |
last post by:
I noticed some quirks with C++ (not sure if this is the same for C).
I have:
struct A {
char a;
};
struct B {
char b;
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: Mushico |
last post by:
How to calculate date of retirement from date of birth
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM)
The start time is equivalent to 19:00 (7PM) in Central...
|
by: Aliciasmith |
last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
|
by: tracyyun |
last post by:
Hello everyone,
I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
|
by: Teri B |
last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course.
0ne-to-many. One course many roles.
Then I created a report based on the Course form and...
|
by: nia12 |
last post by:
Hi there,
I am very new to Access so apologies if any of this is obvious/not clear.
I am creating a data collection tool for health care employees to complete. It consists of a number of...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
| |