Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #149945 > unrolled thread

Offsetof with array elements

Started byDavid Brown <david.brown@hesbynett.no>
First post2020-02-11 15:31 +0100
Last post2020-02-16 16:03 -0800
Articles 20 on this page of 40 — 11 participants

Back to article view | Back to comp.lang.c


Contents

  Offsetof with array elements David Brown <david.brown@hesbynett.no> - 2020-02-11 15:31 +0100
    Re: Offsetof with array elements Guillaume <message@bottle.org> - 2020-02-11 16:08 +0100
      Re: Offsetof with array elements James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-11 08:32 -0800
        Re: Offsetof with array elements David Brown <david.brown@hesbynett.no> - 2020-02-11 18:46 +0100
          Re: Offsetof with array elements Manfred <noname@add.invalid> - 2020-02-11 19:24 +0100
            Re: Offsetof with array elements Manfred <noname@add.invalid> - 2020-02-11 19:36 +0100
            Re: Offsetof with array elements James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-11 22:50 -0500
              Re: Offsetof with array elements Manfred <noname@add.invalid> - 2020-02-12 13:53 +0100
              Re: Offsetof with array elements Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-02-18 01:43 -0800
      Re: Offsetof with array elements Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-02-18 01:39 -0800
    Re: Offsetof with array elements Bart <bc@freeuk.com> - 2020-02-11 16:56 +0000
      Re: Offsetof with array elements David Brown <david.brown@hesbynett.no> - 2020-02-11 18:49 +0100
    Re: Offsetof with array elements Bonita Montero <Bonita.Montero@gmail.com> - 2020-02-11 21:00 +0100
      Re: Offsetof with array elements Bart <bc@freeuk.com> - 2020-02-11 20:13 +0000
        Re: Offsetof with array elements Bonita Montero <Bonita.Montero@gmail.com> - 2020-02-11 21:24 +0100
          Re: Offsetof with array elements Bart <bc@freeuk.com> - 2020-02-11 20:33 +0000
            Re: Offsetof with array elements Bonita Montero <Bonita.Montero@gmail.com> - 2020-02-11 21:39 +0100
              Re: Offsetof with array elements Bart <bc@freeuk.com> - 2020-02-11 20:48 +0000
      Re: Offsetof with array elements David Brown <david.brown@hesbynett.no> - 2020-02-12 10:56 +0100
        Re: Offsetof with array elements Bonita Montero <Bonita.Montero@gmail.com> - 2020-02-12 14:07 +0100
          Re: Offsetof with array elements David Brown <david.brown@hesbynett.no> - 2020-02-12 15:24 +0100
      Re: Offsetof with array elements Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-02-12 10:39 +0000
        Re: Offsetof with array elements Bonita Montero <Bonita.Montero@gmail.com> - 2020-02-12 14:08 +0100
          Re: Offsetof with array elements James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-12 05:29 -0800
            Re: Offsetof with array elements James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-12 11:45 -0800
          Re: Offsetof with array elements Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-02-12 17:50 +0000
        Re: Offsetof with array elements Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-02-16 02:41 -0800
          Re: Offsetof with array elements Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-02-16 11:18 +0000
      Re: Offsetof with array elements already5chosen@yahoo.com - 2020-02-13 02:42 -0800
        Re: Offsetof with array elements James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-14 00:20 -0500
          Re: Offsetof with array elements David Brown <david.brown@hesbynett.no> - 2020-02-14 08:24 +0100
            Re: Offsetof with array elements already5chosen@yahoo.com - 2020-02-14 03:59 -0800
              Re: Offsetof with array elements David Brown <david.brown@hesbynett.no> - 2020-02-14 15:25 +0100
                Re: Offsetof with array elements already5chosen@yahoo.com - 2020-02-16 03:15 -0800
                  Re: Offsetof with array elements David Brown <david.brown@hesbynett.no> - 2020-02-16 14:09 +0100
                    Re: Offsetof with array elements already5chosen@yahoo.com - 2020-02-16 06:36 -0800
            Re: Offsetof with array elements James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-02-15 08:18 -0500
              Re: Offsetof with array elements David Brown <david.brown@hesbynett.no> - 2020-02-15 15:49 +0100
    Re: Offsetof with array elements fir <profesor.fir@gmail.com> - 2020-02-12 04:40 -0800
    Re: Offsetof with array elements "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2020-02-16 16:03 -0800

Page 1 of 2  [1] 2  Next page →


#149945 — Offsetof with array elements

FromDavid Brown <david.brown@hesbynett.no>
Date2020-02-11 15:31 +0100
SubjectOffsetof with array elements
Message-ID<r1udrq$hoe$1@dont-email.me>
#include <stddef.h>

struct S {
    int a[10];
};

int test(int i) {
    return offsetof(struct S, a[i]);
}


Is this allowed in standard C?  It works in most compilers I tried (even
in the most pedantic modes I checked on gcc), but failed in one embedded
compiler.  According to the standard, "offsetof" expands to "an integer
constant expression", and "&s.a[i]" must evaluate to an address constant
(where "s" is an object of type "struct S").

So by my reading, the standard C does not require the expression in
"test" to be valid, and allows a conforming compiler to reject it.
Equally, it does not require a diagnostic, and allows a conforming
compiler to accept it without complaint.

[toc] | [next] | [standalone]


#149946

FromGuillaume <message@bottle.org>
Date2020-02-11 16:08 +0100
Message-ID<r1ug0k$fvk$1@gioia.aioe.org>
In reply to#149945
Le 11/02/2020 à 15:31, David Brown a écrit :
> #include <stddef.h>
> 
> struct S {
>      int a[10];
> };
> 
> int test(int i) {
>      return offsetof(struct S, a[i]);
> }
> 
> 
> Is this allowed in standard C?  It works in most compilers I tried (even
> in the most pedantic modes I checked on gcc), but failed in one embedded
> compiler.  According to the standard, "offsetof" expands to "an integer
> constant expression", and "&s.a[i]" must evaluate to an address constant
> (where "s" is an object of type "struct S").
> 
> So by my reading, the standard C does not require the expression in
> "test" to be valid, and allows a conforming compiler to reject it.
> Equally, it does not require a diagnostic, and allows a conforming
> compiler to accept it without complaint.

 From what I read: "The type and member designator shall be such that 
given static type t; then the expression &(t.member-designator) 
evaluates to an address constant. (If the specified member is a bit-field, 
the behavior is undefined.)"

In your example, &(t.a[i]) would evaluate to an address constant indeed, 
and obviously a[i] doesn't fall into the undefined behavior category as 
it's not a bit field.

There's just a small "but": the standard defines offsetof() with its 
second parameter being a struct member designator. a[i] is not, unless 
I'm mistaken, a member designator, but an expression derived from one. 
Thus you'd be using offsetof() with (IMO) an invalid parameter, and this 
should be reasonably rejected by a conforming compiler. It looks like 
some compilers choose to make this implementation-defined instead. Just 
my opinion on this.

[toc] | [prev] | [next] | [standalone]


#149948

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-02-11 08:32 -0800
Message-ID<0150dd64-4217-49bc-88d0-e8f8925a9dd2@googlegroups.com>
In reply to#149946
"The array-subscript [ ] operator ... may be used in the creation of an address constant, but the value of an object may not be accessed by the use of [that] operator." (6,6p9).

[toc] | [prev] | [next] | [standalone]


#149951

FromDavid Brown <david.brown@hesbynett.no>
Date2020-02-11 18:46 +0100
Message-ID<r1up93$p7n$1@dont-email.me>
In reply to#149948
On 11/02/2020 17:32, James Kuyper wrote:
> "The array-subscript [ ] operator ... may be used in the creation of an address constant, but the value of an object may not be accessed by the use of [that] operator." (6,6p9).
> 

Right.  So since the expression "offsetof(struct S, a[i])" has to access 
the object "i" in order to calculate the address (or the offset, in this 
case), it is disallowed?

[toc] | [prev] | [next] | [standalone]


#149953

FromManfred <noname@add.invalid>
Date2020-02-11 19:24 +0100
Message-ID<r1urgn$856$1@gioia.aioe.org>
In reply to#149951
On 2/11/2020 6:46 PM, David Brown wrote:
> On 11/02/2020 17:32, James Kuyper wrote:
>> "The array-subscript [ ] operator ... may be used in the creation of 
>> an address constant, but the value of an object may not be accessed by 
>> the use of [that] operator." (6,6p9).
>>
> 
> Right.  So since the expression "offsetof(struct S, a[i])" has to access 
> the object "i" in order to calculate the address (or the offset, in this 
> case), it is disallowed?
> 

It sound to me like this part says the address constant creation /is/ 
allowed, since the object is not accessed, i.e. its address is not 
dereferenced. (This is obvious in the common implementation of offsetof 
that places S at address 0).

But the problem still holds for the other part of the specification of 
offsetof, the one pointed out by Guillaume, which is my main doubt as well:

Guillaume wrote:
> the standard defines offsetof() with its second parameter being a struct member designator. a[i] is not, unless I'm mistaken, a member designator, but an expression derived from one. Thus you'd be using offsetof() with (IMO) an invalid parameter

If you look at 7.19p3, the specification of offsetof(type, 
member-designator) has requirements for both /type/ and /member-designator/

The requirement for /member-designator/ uses the wording of the 
Guillaume quote above, the requirement for /type/ refers to the creation 
of an address constant, which is what James' comment is about.

[toc] | [prev] | [next] | [standalone]


#149954

FromManfred <noname@add.invalid>
Date2020-02-11 19:36 +0100
Message-ID<r1us76$bcd$1@gioia.aioe.org>
In reply to#149953
On 2/11/2020 7:24 PM, Manfred wrote:
> On 2/11/2020 6:46 PM, David Brown wrote:
>> On 11/02/2020 17:32, James Kuyper wrote:
>>> "The array-subscript [ ] operator ... may be used in the creation of 
>>> an address constant, but the value of an object may not be accessed 
>>> by the use of [that] operator." (6,6p9).
>>>
>>
>> Right.  So since the expression "offsetof(struct S, a[i])" has to 
>> access the object "i" in order to calculate the address (or the 
>> offset, in this case), it is disallowed?
>>
> 
> It sound to me like this part says the address constant creation /is/ 
> allowed, since the object is not accessed, i.e. its address is not 
> dereferenced. (This is obvious in the common implementation of offsetof 
> that places S at address 0).
> 

Hmm. doubting myself here - "i" is not a constant, thus &s.a[i] is not 
constant either, so how can it be an address constant? Which is probably 
another derivation of your conclusion above.

[toc] | [prev] | [next] | [standalone]


#149961

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-02-11 22:50 -0500
Message-ID<r1vsm9$o3p$1@dont-email.me>
In reply to#149953
On 2/11/20 1:24 PM, Manfred wrote:
> On 2/11/2020 6:46 PM, David Brown wrote:
>> On 11/02/2020 17:32, James Kuyper wrote:
>>> "The array-subscript [ ] operator ... may be used in the creation of 
>>> an address constant, but the value of an object may not be accessed by 
>>> the use of [that] operator." (6,6p9).
>>>
>>
>> Right.  So since the expression "offsetof(struct S, a[i])" has to access 
>> the object "i" in order to calculate the address (or the offset, in this 
>> case), it is disallowed?
>>
> 
> It sound to me like this part says the address constant creation /is/ 
> allowed, since the object is not accessed, i.e. its address is not 
> dereferenced.

The relevant object is "i", not S. And it's the value of the object, not
it's address, which, if accessed, violates that rule. The value stored
in 'i' is needed to determine that offset, so this construct does
violate that rule.

[toc] | [prev] | [next] | [standalone]


#149969

FromManfred <noname@add.invalid>
Date2020-02-12 13:53 +0100
Message-ID<r20sh0$19n3$1@gioia.aioe.org>
In reply to#149961
On 2/12/2020 4:50 AM, James Kuyper wrote:
> On 2/11/20 1:24 PM, Manfred wrote:
>> On 2/11/2020 6:46 PM, David Brown wrote:
>>> On 11/02/2020 17:32, James Kuyper wrote:
>>>> "The array-subscript [ ] operator ... may be used in the creation of
>>>> an address constant, but the value of an object may not be accessed by
>>>> the use of [that] operator." (6,6p9).
>>>>
>>>
>>> Right.  So since the expression "offsetof(struct S, a[i])" has to access
>>> the object "i" in order to calculate the address (or the offset, in this
>>> case), it is disallowed?
>>>
>>
>> It sound to me like this part says the address constant creation /is/
>> allowed, since the object is not accessed, i.e. its address is not
>> dereferenced.
> 
> The relevant object is "i", not S. And it's the value of the object, not
> it's address, which, if accessed, violates that rule. The value stored
> in 'i' is needed to determine that offset, so this construct does
> violate that rule.
> 
Yes, in fact in my follow-up I had an afterthought about "i" as well - 
being an "object" whose value is accessed is substantially incompatible 
with a constant expression (which by definition can be evaluated at 
compile time and may have no storage) - this is to say that the 
requirement that "an object may not be accessed" is to guarantee that an 
address constant is a constant expression (p6.6)

[toc] | [prev] | [next] | [standalone]


#150070

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-02-18 01:43 -0800
Message-ID<86y2t0dydh.fsf@linuxsc.com>
In reply to#149961
James Kuyper <jameskuyper@alumni.caltech.edu> writes:

> On 2/11/20 1:24 PM, Manfred wrote:
>
>> On 2/11/2020 6:46 PM, David Brown wrote:
>>
>>> On 11/02/2020 17:32, James Kuyper wrote:
>>>
>>>> "The array-subscript [ ] operator ... may be used in the creation of
>>>> an address constant, but the value of an object may not be accessed by
>>>> the use of [that] operator."  (6,6p9).
>>>
>>> Right.  So since the expression "offsetof(struct S, a[i])" has to access
>>> the object "i" in order to calculate the address (or the offset, in this
>>> case), it is disallowed?
>>
>> It sound to me like this part says the address constant creation /is/
>> allowed, since the object is not accessed, i.e. its address is not
>> dereferenced.
>
> The relevant object is "i", not S. And it's the value of the object, not
> it's address, which, if accessed, violates that rule.  The value stored
> in 'i' is needed to determine that offset, so this construct does
> violate that rule.

It isn't the use of [] that accesses an object.  It is the lvalue
conversion of 'i' that accesses an object.

[toc] | [prev] | [next] | [standalone]


#150069

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2020-02-18 01:39 -0800
Message-ID<8636b8fd3w.fsf@linuxsc.com>
In reply to#149946
Guillaume <message@bottle.org> writes:

> Le 11/02/2020 at 15:31, David Brown a ecrit:
>
>> #include <stddef.h>
>>
>> struct S {
>>      int a[10];
>> };
>>
>> int test(int i) {
>>      return offsetof(struct S, a[i]);
>> }
>>
>>
>> Is this allowed in standard C?  [...]

Undefined behavior, as was pointed out downthread, because of a
non-constant address calculation.  However, leading into the next
point, what if the address calculation were suitably constant, and so
satisfies the stipulation that "the expression &(t.member-designator)
evaluates to an address constant"?

> [...]
>
> There's just a small "but":  the standard defines offsetof() with its
> second parameter being a struct member designator.  a[i] is not, unless
> I'm mistaken, a member designator, but an expression derived from
> one.  Thus you'd be using offsetof() with (IMO) an invalid parameter,
> and this should be reasonably rejected by a conforming compiler.  It
> looks like some compilers choose to make this implementation-defined
> instead.  Just my opinion on this.

A strict reading of the text of the Standard supports this conclusion,
even if the array index expression were suitably constant.  The
Standard consistently uses the term "stucture member" to mean an
first-level subobject, and not a sub-subobject for any level beyond
the first.  The safest course here would use

    offsetof( struct S, a )

and add in the adjustment for a[i] using sizeof and a multiplication.

Probably this reading is not what was intended for offsetof(), but I
haven't seen any evidence of that.  (Fair disclosure:  I haven't made
any special effort to find any either.)  But a good rule to follow in
cases where the Standard isn't 100% definitive is to err on the side
of caution, choosing the most conservative path reasonably available.
And here that is easy to do, by using the simpler call to offsetof()
shown above, and adjusting the result with a sizeof, etc.

[toc] | [prev] | [next] | [standalone]


#149950

FromBart <bc@freeuk.com>
Date2020-02-11 16:56 +0000
Message-ID<f1B0G.422048$lJ.1756@fx27.am4>
In reply to#149945
On 11/02/2020 14:31, David Brown wrote:
> #include <stddef.h>
> 
> struct S {
>      int a[10];
> };
> 
> int test(int i) {
>      return offsetof(struct S, a[i]);
> }
> 
> 
> Is this allowed in standard C?  It works in most compilers I tried (even
> in the most pedantic modes I checked on gcc), but failed in one embedded
> compiler.  According to the standard, "offsetof" expands to "an integer
> constant expression", and "&s.a[i]" must evaluate to an address constant
> (where "s" is an object of type "struct S").
> 
> So by my reading, the standard C does not require the expression in
> "test" to be valid, and allows a conforming compiler to reject it.
> Equally, it does not require a diagnostic, and allows a conforming
> compiler to accept it without complaint.
> 

I tried this with the expected results on the handful of compilers tested:

--------------------
#include <stdio.h>
#include <stddef.h>

struct S {
     int a[10];
};

int test(int i) {
     return offsetof(struct S, a[i]);
}

int main(void) {
     for (int i=0; i<10; ++i)
         printf("Offset of A[%d] is %d\n",i,test(i));
}
------------------

I say 'expected' but I thought my bcc at least would fail, because I 
consider 'offsetof' a device to return the offset of a struct member, 
which is always going to be a compile-time constant.

It works in my case because offsetof is defined as:

   #define offsetof(a,b) (size_t) &( ((a*)0) -> b)

And the body of test() becomes:

   return(size_t)&(((struct S*)0)->a[i]);

Presumably your odd compiler tries to be too clever.

[toc] | [prev] | [next] | [standalone]


#149952

FromDavid Brown <david.brown@hesbynett.no>
Date2020-02-11 18:49 +0100
Message-ID<r1upf6$rrc$1@dont-email.me>
In reply to#149950
On 11/02/2020 17:56, Bart wrote:
> On 11/02/2020 14:31, David Brown wrote:
>> #include <stddef.h>
>>
>> struct S {
>>      int a[10];
>> };
>>
>> int test(int i) {
>>      return offsetof(struct S, a[i]);
>> }
>>
>>
>> Is this allowed in standard C?  It works in most compilers I tried (even
>> in the most pedantic modes I checked on gcc), but failed in one embedded
>> compiler.  According to the standard, "offsetof" expands to "an integer
>> constant expression", and "&s.a[i]" must evaluate to an address constant
>> (where "s" is an object of type "struct S").
>>
>> So by my reading, the standard C does not require the expression in
>> "test" to be valid, and allows a conforming compiler to reject it.
>> Equally, it does not require a diagnostic, and allows a conforming
>> compiler to accept it without complaint.
>>
> 
> I tried this with the expected results on the handful of compilers tested:
> 
> --------------------
> #include <stdio.h>
> #include <stddef.h>
> 
> struct S {
>      int a[10];
> };
> 
> int test(int i) {
>      return offsetof(struct S, a[i]);
> }
> 
> int main(void) {
>      for (int i=0; i<10; ++i)
>          printf("Offset of A[%d] is %d\n",i,test(i));
> }
> ------------------
> 
> I say 'expected' but I thought my bcc at least would fail, because I 
> consider 'offsetof' a device to return the offset of a struct member, 
> which is always going to be a compile-time constant.
> 
> It works in my case because offsetof is defined as:
> 
>    #define offsetof(a,b) (size_t) &( ((a*)0) -> b)

Yes, that's a common way to define "offsetof".  It involves behaviour 
that is undefined in the C standard (there is AFAIK no way to write the 
offsetof macro using only standards-defined C), but as long as the 
compiler is happy with it, it's no problem.

> 
> And the body of test() becomes:
> 
>    return(size_t)&(((struct S*)0)->a[i]);
> 
> Presumably your odd compiler tries to be too clever.

It sounds like it is justified in rejecting the code, while most 
compilers are more lenient than the standard requires.

[toc] | [prev] | [next] | [standalone]


#149955

FromBonita Montero <Bonita.Montero@gmail.com>
Date2020-02-11 21:00 +0100
Message-ID<r1v150$nb7$1@news.albasani.net>
In reply to#149945
How about this:

#include <stddef.h>
#define array_offsetof(type, member, index) (size_t)(offsetof(type, 
member) + sizeof(((type *)NULL)->##member[0]) * index)

[toc] | [prev] | [next] | [standalone]


#149956

FromBart <bc@freeuk.com>
Date2020-02-11 20:13 +0000
Message-ID<YVD0G.293006$j92.144407@fx14.am4>
In reply to#149955
On 11/02/2020 20:00, Bonita Montero wrote:
> How about this:
> 
> #include <stddef.h>
> #define array_offsetof(type, member, index) (size_t)(offsetof(type, 
> member) + sizeof(((type *)NULL)->##member[0]) * index)

Did you test it? It fails on most (not all) compilers including gcc.

This version seems to work on all the ones I tried:

   #define array_offsetof(type, member, index) \
    (offsetof(type, member) + sizeof( ((type *)0)->member[0]) * index)

It's invoked like this:

   return array_offsetof(struct S, a, i);

[toc] | [prev] | [next] | [standalone]


#149957

FromBonita Montero <Bonita.Montero@gmail.com>
Date2020-02-11 21:24 +0100
Message-ID<r1v2hi$f30$1@news.albasani.net>
In reply to#149956
>> How about this:
>>
>> #include <stddef.h>
>> #define array_offsetof(type, member, index) (size_t)(offsetof(type, 
>> member) + sizeof(((type *)NULL)->##member[0]) * index)

> Did you test it? It fails on most (not all) compilers including gcc.
> This version seems to work on all the ones I tried:
>    #define array_offsetof(type, member, index) \
>     (offsetof(type, member) + sizeof( ((type *)0)->member[0]) * index)
> It's invoked like this:
>    return array_offsetof(struct S, a, i);

Don't know why, but my version works when compiled as C++ and not
as C. I thought that might be o.k. for C also.
But I'm wondering why you won't have to write (struct type *) but
(type *). Did you typedef ?

[toc] | [prev] | [next] | [standalone]


#149958

FromBart <bc@freeuk.com>
Date2020-02-11 20:33 +0000
Message-ID<IcE0G.98236$cW.40397@fx16.am4>
In reply to#149957
On 11/02/2020 20:24, Bonita Montero wrote:
>>> How about this:
>>>
>>> #include <stddef.h>
>>> #define array_offsetof(type, member, index) (size_t)(offsetof(type, 
>>> member) + sizeof(((type *)NULL)->##member[0]) * index)
> 
>> Did you test it? It fails on most (not all) compilers including gcc.
>> This version seems to work on all the ones I tried:
>>    #define array_offsetof(type, member, index) \
>>     (offsetof(type, member) + sizeof( ((type *)0)->member[0]) * index)
>> It's invoked like this:
>>    return array_offsetof(struct S, a, i);
> 
> Don't know why, but my version works when compiled as C++ and not
> as C. I thought that might be o.k. for C also.
> But I'm wondering why you won't have to write (struct type *) but
> (type *). Did you typedef ?

No. That means that in C, the 'type' of the stuct is 'struct S' rather 
than just 'S' if you do this:

  typedef struct S S;

[toc] | [prev] | [next] | [standalone]


#149959

FromBonita Montero <Bonita.Montero@gmail.com>
Date2020-02-11 21:39 +0100
Message-ID<r1v3e3$dvl$1@news.albasani.net>
In reply to#149958
>>>> How about this:
>>>>
>>>> #include <stddef.h>
>>>> #define array_offsetof(type, member, index) (size_t)(offsetof(type, 
>>>> member) + sizeof(((type *)NULL)->##member[0]) * index)
>>
>>> Did you test it? It fails on most (not all) compilers including gcc.
>>> This version seems to work on all the ones I tried:
>>>    #define array_offsetof(type, member, index) \
>>>     (offsetof(type, member) + sizeof( ((type *)0)->member[0]) * index)
>>> It's invoked like this:
>>>    return array_offsetof(struct S, a, i);
>>
>> Don't know why, but my version works when compiled as C++ and not
>> as C. I thought that might be o.k. for C also.
>> But I'm wondering why you won't have to write (struct type *) but
>> (type *). Did you typedef ?
> 
> No. That means that in C, the 'type' of the stuct is 'struct S' rather 
> than just 'S' if you do this:
> 
>   typedef struct S S;

Of course, but you wrote "((type *)0)->member[0])" without struct.
So you rely on a duplicate typedef.

[toc] | [prev] | [next] | [standalone]


#149960

FromBart <bc@freeuk.com>
Date2020-02-11 20:48 +0000
Message-ID<sqE0G.342067$UPz1.332158@fx15.am4>
In reply to#149959
On 11/02/2020 20:39, Bonita Montero wrote:
>>>>> How about this:
>>>>>
>>>>> #include <stddef.h>
>>>>> #define array_offsetof(type, member, index) (size_t)(offsetof(type, 
>>>>> member) + sizeof(((type *)NULL)->##member[0]) * index)
>>>
>>>> Did you test it? It fails on most (not all) compilers including gcc.
>>>> This version seems to work on all the ones I tried:
>>>>    #define array_offsetof(type, member, index) \
>>>>     (offsetof(type, member) + sizeof( ((type *)0)->member[0]) * index)
>>>> It's invoked like this:
>>>>    return array_offsetof(struct S, a, i);
>>>
>>> Don't know why, but my version works when compiled as C++ and not
>>> as C. I thought that might be o.k. for C also.
>>> But I'm wondering why you won't have to write (struct type *) but
>>> (type *). Did you typedef ?
>>
>> No. That means that in C, the 'type' of the stuct is 'struct S' rather 
>> than just 'S' if you do this:
>>
>>   typedef struct S S;
> 
> Of course, but you wrote "((type *)0)->member[0])" without struct.
> So you rely on a duplicate typedef.


'type' is the name of a macro parameter. The macro argument was 'struct S':

    return array_offsetof(struct S, a, i);

I could have chosen to insert 'struct' into the macro body, but then it 
could only be invoked with a struct tag name, not either 'struct tag' or 
a typedefed struct.

[toc] | [prev] | [next] | [standalone]


#149964

FromDavid Brown <david.brown@hesbynett.no>
Date2020-02-12 10:56 +0100
Message-ID<r20i4t$qjo$1@dont-email.me>
In reply to#149955
On 11/02/2020 21:00, Bonita Montero wrote:
> How about this:
> 
> #include <stddef.h>
> #define array_offsetof(type, member, index) (size_t)(offsetof(type,
> member) + sizeof(((type *)NULL)->##member[0]) * index)

I have no problem finding the offset to the array item.  My question was
about whether it can be done portably using offsetof directly - was this
a bug or limitation in the one particular compiler, or are other
compilers being helpfully lenient?  (The conclusion seems to be the later.)

[toc] | [prev] | [next] | [standalone]


#149970

FromBonita Montero <Bonita.Montero@gmail.com>
Date2020-02-12 14:07 +0100
Message-ID<r20tan$b9b$2@news.albasani.net>
In reply to#149964
> I have no problem finding the offset to the array item. ...

So your question is a waste of time.

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | comp.lang.c


csiph-web