Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #9819 > unrolled thread
| Started by | "skillzero@gmail.com" <skillzero@gmail.com> |
|---|---|
| First post | 2011-09-01 08:28 -0700 |
| Last post | 2011-09-01 22:05 -0700 |
| Articles | 7 — 7 participants |
Back to article view | Back to comp.lang.c
Compliant way to use offsetof for a field within a field? "skillzero@gmail.com" <skillzero@gmail.com> - 2011-09-01 08:28 -0700
Re: Compliant way to use offsetof for a field within a field? James Kuyper <jameskuyper@verizon.net> - 2011-09-01 12:23 -0400
Re: Compliant way to use offsetof for a field within a field? "J. J. Farrell" <jjf@bcs.org.uk> - 2011-09-02 00:34 +0100
Re: Compliant way to use offsetof for a field within a field? "christian.bau" <christian.bau@cbau.wanadoo.co.uk> - 2011-09-01 10:19 -0700
Re: Compliant way to use offsetof for a field within a field? Peter Nilsson <airia@acay.com.au> - 2011-09-01 16:31 -0700
Re: Compliant way to use offsetof for a field within a field? Andrey Tarasevich <andreytarasevich@hotmail.com> - 2011-09-01 16:38 -0700
Re: Compliant way to use offsetof for a field within a field? Michael Press <rubrum@pacbell.net> - 2011-09-01 22:05 -0700
| From | "skillzero@gmail.com" <skillzero@gmail.com> |
|---|---|
| Date | 2011-09-01 08:28 -0700 |
| Subject | Compliant way to use offsetof for a field within a field? |
| Message-ID | <fbfb883a-2d39-4aa4-832f-de302fac65c7@j4g2000prh.googlegroups.com> |
Is there a compliant way of getting the offset of a field within a
field? I'm mainly using this to do compile-time checks that fields are
at the offset I expect them. I'm using offsetof( NameOfStruct,
field1.field2 ) now and this works, but with some compilers, I'm
getting a warning about "Using extended field designator is an
extension". Here's an example:
typedef struct
{
uint8_t x;
uint8_t y;
struct
{
uint8_t z;
} fields;
} Test;
compile_time_assert( offsetof( Test, x ) == 0 ); // Works
compile_time_assert( offsetof( Test, y ) == 1 ); // Works
compile_time_assert( offsetof( Test, fields.z ) == 2 ); // Works, but
warns about an extension.
Is there a way to do this in a compliant way?
[toc] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2011-09-01 12:23 -0400 |
| Message-ID | <4E5FB187.7030305@verizon.net> |
| In reply to | #9819 |
On 09/01/2011 11:28 AM, skillzero@gmail.com wrote:
> Is there a compliant way of getting the offset of a field within a
> field? I'm mainly using this to do compile-time checks that fields are
> at the offset I expect them. I'm using offsetof( NameOfStruct,
> field1.field2 ) now and this works, but with some compilers, I'm
> getting a warning about "Using extended field designator is an
> extension". Here's an example:
>
> typedef struct
> {
> uint8_t x;
> uint8_t y;
> struct
> {
> uint8_t z;
>
> } fields;
>
> } Test;
>
> compile_time_assert( offsetof( Test, x ) == 0 ); // Works
There's not much point in testing that one: on a conforming
implementation of C, it's guaranteed to be 0.
> compile_time_assert( offsetof( Test, y ) == 1 ); // Works
> compile_time_assert( offsetof( Test, fields.z ) == 2 ); // Works, but
> warns about an extension.
>
> Is there a way to do this in a compliant way?
offsetof(Test,fields) should give you the offset of z, for the same
reason that offsetof(Test,x) should give you a 0.
Of course, that answer wouldn't help if "fields" had multiple members.
The solution is to give "fields" a named type:
struct some_name {
uint8_t z;
double d;
} fields;
Then, instead of testing for offsetof(Test, fields.d), test separately
for offsetof(Test, fields) and offsetof(struct some_name, d).
[toc] | [prev] | [next] | [standalone]
| From | "J. J. Farrell" <jjf@bcs.org.uk> |
|---|---|
| Date | 2011-09-02 00:34 +0100 |
| Message-ID | <j3p4pm$7eq$1@dont-email.me> |
| In reply to | #9825 |
James Kuyper wrote:
> On 09/01/2011 11:28 AM, skillzero@gmail.com wrote:
>> Is there a compliant way of getting the offset of a field within a
>> field? I'm mainly using this to do compile-time checks that fields are
>> at the offset I expect them. I'm using offsetof( NameOfStruct,
>> field1.field2 ) now and this works, but with some compilers, I'm
>> getting a warning about "Using extended field designator is an
>> extension". Here's an example:
>>
>> typedef struct
>> {
>> uint8_t x;
>> uint8_t y;
>> struct
>> {
>> uint8_t z;
>>
>> } fields;
>>
>> } Test;
>>
>> compile_time_assert( offsetof( Test, x ) == 0 ); // Works
>
> There's not much point in testing that one: on a conforming
> implementation of C, it's guaranteed to be 0.
One common reason for testing that is to protect against someone later
modifying the structure by putting something in front of x. It's
certainly not needed if the purpose is to check that assumptions about
padding are valid; but if the purpose is to check that certain fields in
the structure match certain externally defined data, then it protects
against changes by people who don't understand all the implications of
what they're doing.
[toc] | [prev] | [next] | [standalone]
| From | "christian.bau" <christian.bau@cbau.wanadoo.co.uk> |
|---|---|
| Date | 2011-09-01 10:19 -0700 |
| Message-ID | <9a909a63-8328-49b8-a0a4-bdf34c67ab06@k9g2000vbd.googlegroups.com> |
| In reply to | #9819 |
On Sep 1, 4:28 pm, "skillz...@gmail.com" <skillz...@gmail.com> wrote:
> Is there a compliant way of getting the offset of a field within a
> field? I'm mainly using this to do compile-time checks that fields are
> at the offset I expect them. I'm using offsetof( NameOfStruct,
> field1.field2 ) now and this works, but with some compilers, I'm
> getting a warning about "Using extended field designator is an
> extension". Here's an example:
>
> typedef struct
> {
> uint8_t x;
> uint8_t y;
> struct
> {
> uint8_t z;
>
> } fields;
>
> } Test;
>
> compile_time_assert( offsetof( Test, x ) == 0 ); // Works
> compile_time_assert( offsetof( Test, y ) == 1 ); // Works
> compile_time_assert( offsetof( Test, fields.z ) == 2 ); // Works, but
> warns about an extension.
>
> Is there a way to do this in a compliant way?
First, you need to give the struct used for "fields" a name so that it
can be used in offsetof. Let's say you typedef'd it as "Field". Then
you write
offsetof (Test, fields) + offsetof (Fields, z) == 2.
[toc] | [prev] | [next] | [standalone]
| From | Peter Nilsson <airia@acay.com.au> |
|---|---|
| Date | 2011-09-01 16:31 -0700 |
| Message-ID | <453f9879-47e4-4429-9587-293c04112340@e20g2000prn.googlegroups.com> |
| In reply to | #9828 |
"christian.bau" <christian....@cbau.wanadoo.co.uk> wrote:
> "skillz...@gmail.com" <skillz...@gmail.com> wrote:
> > typedef struct
> > {
> > uint8_t x;
> > uint8_t y;
> > struct
> > {
> > uint8_t z;
> > } fields;
> > } Test;
> >
> > compile_time_assert( offsetof( Test, x ) == 0 ); // Works
> > compile_time_assert( offsetof( Test, y ) == 1 ); // Works
> > compile_time_assert( offsetof( Test, fields.z ) == 2 ); // Works,
> > but warns about an extension.
> >
> > Is there a way to do this in a compliant way?
>
> First, you need to give the struct used for "fields" a name so that
> it can be used in offsetof.
To nitpick, you don't strictly need to name the struct. You can do...
offsetof(struct { uint8_t z; }, z)
But that's a maintenance nightmare.
> Let's say you typedef'd it as "Field".
> Then you write
>
> offsetof (Test, fields) + offsetof (Fields, z) == 2.
ITYM offsetof (Field, z)
--
Peter
[toc] | [prev] | [next] | [standalone]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2011-09-01 16:38 -0700 |
| Message-ID | <j3p4vr$8ah$1@dont-email.me> |
| In reply to | #9819 |
On 9/1/2011 8:28 AM, skillzero@gmail.com wrote:
>
> typedef struct
> {
> uint8_t x;
> uint8_t y;
> struct
> {
> uint8_t z;
>
> } fields;
>
> } Test;
>
> compile_time_assert( offsetof( Test, x ) == 0 ); // Works
> compile_time_assert( offsetof( Test, y ) == 1 ); // Works
> compile_time_assert( offsetof( Test, fields.z ) == 2 ); // Works, but
> warns about an extension.
>
> Is there a way to do this in a compliant way?
What compiler are you using? Are you sure you are not compiling your
code as C++ code?
The `offsetof( Test, fields.z )` _is_ the compliant way in C. There are
no extensions of any kind involved here.
The specification of `offsetof` is C language only requires that
`&object.member_designator` be an address constant (for some imagginary
static object `object`). There's no requirement for the
'member_designator' to designate the immediate member of the structure.
It is perfectly allowed to use `offsetof` with "deeper" members of the
struct type.
--
Best regards,
Andrey Tarasevich
[toc] | [prev] | [next] | [standalone]
| From | Michael Press <rubrum@pacbell.net> |
|---|---|
| Date | 2011-09-01 22:05 -0700 |
| Message-ID | <rubrum-2179E2.22050301092011@news.albasani.net> |
| In reply to | #9819 |
In article
<fbfb883a-2d39-4aa4-832f-de302fac65c7@j4g2000prh.googlegroups.com>,
"skillzero@gmail.com" <skillzero@gmail.com> wrote:
> Is there a compliant way of getting the offset of a field within a
> field? I'm mainly using this to do compile-time checks that fields are
> at the offset I expect them. I'm using offsetof( NameOfStruct,
> field1.field2 ) now and this works, but with some compilers, I'm
> getting a warning about "Using extended field designator is an
> extension". Here's an example:
>
> typedef struct
> {
> uint8_t x;
> uint8_t y;
> struct
> {
> uint8_t z;
>
> } fields;
>
> } Test;
>
> compile_time_assert( offsetof( Test, x ) == 0 ); // Works
> compile_time_assert( offsetof( Test, y ) == 1 ); // Works
> compile_time_assert( offsetof( Test, fields.z ) == 2 ); // Works, but
> warns about an extension.
>
> Is there a way to do this in a compliant way?
Set each structure field to distinct bit patterns.
Find sizeof(Test).
Dump the the entire struct into a buffer with memcpy or some such.
Analyze the contents of the buffer.
This method is known as extispicy.
--
Michael Press
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c
csiph-web