Topic: offsetof and run-time offsets


Author: skaller@users.sourceforge.net (skaller)
Date: Fri, 10 Mar 2006 18:19:11 GMT
Raw View
On Tue, 07 Mar 2006 15:41:49 +0000, Fred Zwarts wrote:

> Therefore I asked for a general solution.

What you really need is the algebraic completion of
pointers to members. Which I proposed but it was ignored.
Basically the rules are given by:

 p .* ( a .* b) = (p .* a) .* b

 p .* ( a + i) = (p .* a) + i

etc. In each case we're defining the subexpression on
the LHS inside the brackets. This is more compact
that using casts and sizeof, and it is typesafe.
But you can't do it because no one thought it was
important.

You can easily implement all these operations with
templates using a integer as the internal representation,
initially obtained using the offsetof() macro.
Apart from initial construction, the calculations are
typesafe .. and the notation

 ptm<S,M>

is actually more readable than the native pointer to member
syntax IMHO. AFAICS most of this could be done in the library.
Pity we cannot make ptm<S,M> an alias for a pointer to member
(due to lack of templated typedefs).

--
John Skaller <skaller at users dot sourceforge dot net>
Async P/L, Realtime software consultants
Felix for C/C++ programmers http://felix.sourceforge.net


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: skaller@users.sourceforge.net (skaller)
Date: Tue, 14 Mar 2006 15:11:57 GMT
Raw View
On Wed, 08 Mar 2006 15:46:19 +0000, Fred Zwarts wrote:

>
> 3
> I still don't completely get the rationale behind the restriction for offsetof.


* The macro is a simple part of the C language
which implementors can easily define in one line.

* There is no need to extend its behaviour to run time
expressions, since you can do all the calculations you need
to do with it defined as it is. It's just painful :)

* There is in fact a serious defect in the C++ definition,
which is that offsetof() can only be applied to a POD.
This rules out an aggregate that happens to have a constructible
member, or a class which itself happens to have a constructor.
There is no good reason for that, and there is a very good reason
why that restriction must be removed -- without the restriction
being removed certain calculations are entirely impossible.
The only restriction that makes sense is calculating offsets
across virtual base boundaries.

* if you want a shorthand way of calculating run time
offsets you should read my previous post. You can do it
yourself easily with templates, and achieve type safety
at the same time. The type safety is not a free extra,
it is precisely what simplifies the calculations
(knowing the sizeof() the types involved).

* the only caveat is that such template based offset
calculations do not play with C++ built in type safe
offset construction, pointers to members, because
pointers to members are themselves grossly inadequate.
That is also a serious defect in the standard.

In particular if this defect were remedied, then the
need for the unsafe offsetof() macro would be greatly
reduced. It may still be needed for implementing
memory managers however -- I have an such an application
where pointers to members would not suffice (it's
a garbage collector). Unless they support suitable
degenerate cases (void* kind of stuff).

THUS -- there really are TWO serious defects in the arena
you are playing, but repairing them does not and should
not entail changing offsetof() to do runtime calculations.

What you want to do is reasonable but the way you think
it should be done is not. IMHO. :)

--
John Skaller <skaller at users dot sourceforge dot net>
Async P/L, Realtime software consultants
Felix for C/C++ programmers http://felix.sourceforge.net


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Mon, 6 Mar 2006 21:42:15 GMT
Raw View
Fred Zwarts ha scritto:
> However, I now have a new compiler which uses a built-in function inste=
ad of this macro.
> A error message is generated at compile time for my use of offsetof bec=
ause
> this built-in function requires that the offset is a compile-time const=
ant.=20
> I understand that there is some discussion about the exact wording and =
interpretation=20
> of the standard with respect to the constant requirement for offsetof.=20
>=20
> My first question is what is the rationale behind this requirement in t=
he C++ standard?

Yes. It's standard. The requirement of offsetof are stated in the C
standard at =A77.17/3:

"[offsetof] expands to an integer constant expression that has type
size_t, the value of which is the offset in bytes, [...]. The type and
member designator shall be such that given

  static type t;

then the expression &(t.member-designator) evaluates to an address
constant."

(Notice that there are additional requirement for offsetof in C++, but
they are irrelevant to our case, see =A718.1/5).

The fact the offsetof might work on certain implementations in cases
where the the result is not an integer constant expression is to be
considered a non-standard extension of such implementations.

> There clearly is a need for offsetof for offsets that are not constant.

Really? I never felt such need. Can you provide a use case where it is
needed (and where you can't use the workaround below)?

> My second question is what other method(s) the standard offers to calcu=
late an offset that is=20
> not a constant. (Not for this particular struct, but in the general cas=
e.)

In this case it's very simple: instead of offsetof(s, b[i]), just use
offsetof(s, b) + i * sizeof(b[0]).

HTH,

Ganesh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: F.Zwarts@KVI.nl ("Fred Zwarts")
Date: Tue, 7 Mar 2006 15:41:49 GMT
Raw View

"Alberto Ganesh Barbati" <AlbertoBarbati@libero.it> wrote in message news=
:DU1Pf.22110$A83.626973@twister1.libero.it...
> Fred Zwarts ha scritto:
>> However, I now have a new compiler which uses a built-in function inst=
ead of this macro.
>> A error message is generated at compile time for my use of offsetof be=
cause
>> this built-in function requires that the offset is a compile-time cons=
tant.=20
>> I understand that there is some discussion about the exact wording and=
 interpretation=20
>> of the standard with respect to the constant requirement for offsetof.=
=20
>>=20
>> My first question is what is the rationale behind this requirement in =
the C++ standard?
>
> Yes. It's standard. The requirement of offsetof are stated in the C
> standard at =A77.17/3:
>
> "[offsetof] expands to an integer constant expression that has type
> size_t, the value of which is the offset in bytes, [...]. The type and
> member designator shall be such that given
>
>  static type t;
>
> then the expression &(t.member-designator) evaluates to an address
> constant."
>
> (Notice that there are additional requirement for offsetof in C++, but
> they are irrelevant to our case, see =A718.1/5).
>
> The fact the offsetof might work on certain implementations in cases
> where the the result is not an integer constant expression is to be
> considered a non-standard extension of such implementations.
>
>> There clearly is a need for offsetof for offsets that are not constant.
>
> Really? I never felt such need. Can you provide a use case where it is
> needed (and where you can't use the workaround below)?

I have such a need. You only provide a workaround for a very simple case.
I need a solution for the general case. If there is no such general solut=
ion
within the C++ standard I also would like to know.
I don't want to design a different workaround for each different struct.

The specific case where I need this is hardware related. I have memory
that can not be addressed as normal memory using pointers, but only using=
=20
functions to read 8, 16, or 32 bit entities.=20
These functions have a parameter of an integer type, that is called the a=
ddress.=20
In order to map my struct on this memory, I need offsets from a certain b=
ase address.

>> My second question is what other method(s) the standard offers to calc=
ulate an offset that is=20
>> not a constant. (Not for this particular struct, but in the general ca=
se.)
>
> In this case it's very simple: instead of offsetof(s, b[i]), just use
> offsetof(s, b) + i * sizeof(b[0]).

Yes, I said already that in the real world my structs are more complex.
If b was declared as
  int b[sizeA][sizeB][sizeC];
I have to write out the whole indexing arithmetic to get the offset of b[=
i][j][k].
I would like the compiler to perform this arithmetic for me.
It can become even more complex with arrays of structs.

Therefore I asked for a general solution.

You explained the fact that offsetof has the constant requirement for its=
 second parameter,
but that is not what I asked. I asked about the rationale behind this req=
uirement.
Why is there such a restriction in the standard  if almost all compiler e=
nvironments used to have
a macro that did not have this limitation?

Fred.Zwarts.


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: terminatorul@gmail.com (Timothy Madden)
Date: Tue, 7 Mar 2006 17:23:26 GMT
Raw View
Alberto Ganesh Barbati wrote:
> Fred Zwarts ha scritto:
>=20
>>However, I now have a new compiler which uses a built-in function inste=
ad of this macro.
>>A error message is generated at compile time for my use of offsetof bec=
ause
>>this built-in function requires that the offset is a compile-time const=
ant.=20
>>I understand that there is some discussion about the exact wording and =
interpretation=20
>>of the standard with respect to the constant requirement for offsetof.=20
>>
>>My first question is what is the rationale behind this requirement in t=
he C++ standard?
>=20
>=20
> Yes. It's standard. The requirement of offsetof are stated in the C
> standard at =A77.17/3:
>=20
> "[offsetof] expands to an integer constant expression that has type
> size_t, the value of which is the offset in bytes, [...]. The type and
> member designator shall be such that given
>=20
>   static type t;
>=20
> then the expression &(t.member-designator) evaluates to an address
> constant."

I think offsetof should be implemented in the compiler (even be a=20
keyword). It should allow either a class type or an object of class=20
type, and either a type member or a memeber of that same object. Should=20
be compile-time constant when possible, or a run-time expression=20
otherwise. Actualy it could allow even arrays/array types and=20
indexes/array elements. It should return (char *)&obj.member - (char *)&o=
bj.

I also think compilers should have a lengthof operator to return the=20
length of an array. I so much need such an operator. Also a keyword.

Thank you
Timothy Madden
Romania

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 7 Mar 2006 17:53:11 GMT
Raw View
Timothy Madden wrote:
> I think offsetof should be implemented in the compiler

It is implemented by the compiler. It's defined to be a
macro, but the contents of that macro are controlled by
the implementation.

> Should be compile-time constant when possible,
 > or a run-time expression otherwise.

To be useful, you would have to define the "when possible".
No one cares enough to pick through all the cases to figure
this out. Well, unless you do, in which case submit your
proposal.

> I also think compilers should have a lengthof operator to return the
> length of an array. I so much need such an operator. Also a keyword.

It's probably already in Boost, but this is easily written in
standard C++:

#include <memory>
template<typename T, size_t N> char (&_length_of(T (&array)[N]))[N];
#define lengthof(array) sizeof(_length_of(array))

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 8 Mar 2006 03:49:59 GMT
Raw View
Fred Zwarts wrote:
> The specific case where I need this is hardware related. I have memory
> that can not be addressed as normal memory using pointers, but only using
> functions to read 8, 16, or 32 bit entities.
> These functions have a parameter of an integer type, that is called the address.
> In order to map my struct on this memory, I need offsets from a certain base address.
>
> If b was declared as
>   int b[sizeA][sizeB][sizeC];
> I have to write out the whole indexing arithmetic to get the offset of b[i][j][k].
> I would like the compiler to perform this arithmetic for me.
> It can become even more complex with arrays of structs.
>
> Therefore I asked for a general solution.

You need to be working in the Ada programming language.
If you ask on comp.lang.ada, someone there will be happy
to get you started. There are free Ada compilers available
if cost is an issue.

> You explained the fact that offsetof has the constant requirement for its second parameter,
> but that is not what I asked. I asked about the rationale behind this requirement.

The offsetof macro dates back from the C standard, where it was
invented as a portable means for specifying a fixed offset from
the beginning of a structure, which was formerly typically coded
as ((unsigned)(&((struct t *)0)->field)). It's likely that this will
work for you for the b[i][j][k] case, but it's formally undefined
behavior. Go ahead and try it anyway.

In most cases, people want the result of offsetof to be a constant
expression, and no one cared enough to bother coming up with a way
of saying "constant for these cases, not constant for others". Just
make up your own macros. Or better yet, see above and use Ada.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "frege" <gottlobfrege@gmail.com>
Date: Tue, 7 Mar 2006 22:28:11 CST
Raw View
"Fred Zwarts" wrote:
> Consider the following definition:
>
> For most compiler environments offsetof is defined as a macro as follows
> in stddef.h:
>
> #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
>
> and in these cases my function works as I expected..
>
> However, I now have a new compiler which uses a built-in function instead of this macro.
> A error message is generated at compile time for my use of offsetof because
> this built-in function requires that the offset is a compile-time constant.
> I understand that there is some discussion about the exact wording and interpretation
> of the standard with respect to the constant requirement for offsetof.
>

> My second question is what other method(s) the standard offers to calculate an offset that is
> not a constant. (Not for this particular struct, but in the general case.)
>

You alraedy have an answer:

> #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
>

So just make your own macro:

#define OFFSETOF(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)


> Regards,
> Fred.Zwarts.
>

Tony

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: F.Zwarts@KVI.nl ("Fred Zwarts")
Date: Wed, 8 Mar 2006 15:46:19 GMT
Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:E1FGemc-0002sM-00@chx400.switch.ch...
> Fred Zwarts wrote:
>> The specific case where I need this is hardware related. I have memory
>> that can not be addressed as normal memory using pointers, but only using
>> functions to read 8, 16, or 32 bit entities.
>> These functions have a parameter of an integer type, that is called the address.
>> In order to map my struct on this memory, I need offsets from a certain base address.
>>
>> If b was declared as
>>   int b[sizeA][sizeB][sizeC];
>> I have to write out the whole indexing arithmetic to get the offset of b[i][j][k].
>> I would like the compiler to perform this arithmetic for me.
>> It can become even more complex with arrays of structs.
>>
>> Therefore I asked for a general solution.
>
> You need to be working in the Ada programming language.
> If you ask on comp.lang.ada, someone there will be happy
> to get you started. There are free Ada compilers available
> if cost is an issue.
>
>> You explained the fact that offsetof has the constant requirement for its second parameter,
>> but that is not what I asked. I asked about the rationale behind this requirement.
>
> The offsetof macro dates back from the C standard, where it was
> invented as a portable means for specifying a fixed offset from
> the beginning of a structure, which was formerly typically coded
> as ((unsigned)(&((struct t *)0)->field)). It's likely that this will
> work for you for the b[i][j][k] case, but it's formally undefined
> behavior. Go ahead and try it anyway.
>
> In most cases, people want the result of offsetof to be a constant
> expression, and no one cared enough to bother coming up with a way
> of saying "constant for these cases, not constant for others". Just
> make up your own macros. Or better yet, see above and use Ada.

1
I once worked with Ada and liked many aspects of the language.
However, in the given case there are other considerations that
made us choose for C++.

2
You say that the above macro is formally undefined.
Are you saying that within strict standard C++ there is no way to
calculate a run-time offset in a general way such that the compiler
performs the whole arithmetic of indexing and offsets of nested structs?
(For the moment I can use a macro like the one above. It will be used
a lot in our software. But I am afraid to build in a time-bomb. If a new
version of the compiler (or a compiler on a new platform) makes the
formally undefined result really unusable, I want to be sure that it is
possible to write another macro of the form RunTimeOffsetOf (R,S) that
calculates the desired offset. I have not yet found one that has a formally
defined result and I wonder whether it is possible.)

3
I still don't completely get the rationale behind the restriction for offsetof.
As you said, on almost all platforms the offsetof is defined as a macro
like you show above. This macro works fine for run-time offsets, too.
Compilers are perfectly able to determine when the above macro results
in a constant expression and when it is a run-time expression.

(In fact I did not know of this restriction of offsetof and I used offsetof for
run-time offsets for many years without problems on many platforms.
It was only last month I discovered that later versions of the gnu compiler
refused to compile this code and that this is due to the limitation imposed by
the standard.)


Fred.Zwarts.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kuyper@wizard.net
Date: Wed, 8 Mar 2006 10:44:24 CST
Raw View
"Fred Zwarts" wrote:
> "Hyman Rosen" <hyrosen@mail.com> wrote in message news:E1FGemc-0002sM-00@chx400.switch.ch...
.
> > as ((unsigned)(&((struct t *)0)->field)). It's likely that this will
.
> 2
> You say that the above macro is formally undefined.

More precisely, the behavior that results from using that macro is
undefined. The key problem is the (struct t *)0)->field sub-expression.
It dereferences a pointer value that's not guaranteed to be
dereferenceable. the fact that it does so only in order to be able to
apply the & operator doesn't matter, as far as the standard is
concerned.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: AlbertoBarbati@libero.it (Alberto Ganesh Barbati)
Date: Thu, 9 Mar 2006 00:14:05 GMT
Raw View
Fred Zwarts ha scritto:
> Are you saying that within strict standard C++ there is no way to
> calculate a run-time offset in a general way such that the compiler
> performs the whole arithmetic of indexing and offsets of nested structs?

The compiler is able to perform the computation you desire *as long as*
it has an object to work onto. The offsetof() magic is exactly to
compute the offset given the type alone and in absence of an instance of
such type. That's what the (struct t *)0 does! Unfortunately, it's
undefined behaviour, therefore it's not portable.

> (For the moment I can use a macro like the one above. It will be used
> a lot in our software. But I am afraid to build in a time-bomb. If a new
> version of the compiler (or a compiler on a new platform) makes the
> formally undefined result really unusable, I want to be sure that it is
> possible to write another macro of the form RunTimeOffsetOf (R,S) that
> calculates the desired offset. I have not yet found one that has a formally
> defined result and I wonder whether it is possible.)

A code that might (see below about the use of "might") have chance to
succeed is the following:

template <typename T> struct singleton
{
  static T instance;
};

template <typename T>
T singleton<T>::instance;

#define my_offsetof(s, m)
(reinterpret_cast<char*>(&(singleton<s>::instance.m)) -
reinterpret_cast<char*>(&singleton<s>::instance))

At least the result of this code is "implementation defined" rather than
"undefined behaviour". That means it surely compile and produce a
result, but results might be wrong if the reinterpret_cast<> in
implemented in some exotic way. However, AFAIK it works at least on all
platform I usually use. The only issue is that it must instantiate an
object of each type used, which may be undesirable if your structure are
very large and memory is scarce.

HTH,

Ganesh

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 9 Mar 2006 00:19:59 GMT
Raw View
Fred Zwarts wrote:
> Are you saying that within strict standard C++ there is no way to
> calculate a run-time offset in a general way such that the compiler
> performs the whole arithmetic of indexing and offsets of nested structs?

It can be done only if you have an actual object of the type you're
dealing with. Then you can rewrite offsetof as

     #define offsetof(object, field) \
 (((unsigned long)(void *)&((object).field)) - \
           (unsigned long)(void *)&( object       ))

You need an integer type that can hold any pointer,
and you need a compiler that doesn't do any significant
craziness on the reinterpret_cast to void *, but that
holds pretty much anywhere. This is no longer a constant
expression, but that's fine for you.

> Compilers are perfectly able to determine when the above macro results
> in a constant expression and when it is a run-time expression.

The problem is that the standard has to say *something*. If it said
"the result of offsetof is sometimes a constant expression and other
times not" there would be quite a number of peeved users who would
complain, because they would want to use constant expressions and
they wouldn't be able to because the standard wasn't telling them
when their code would be legal. So as I said, the problem is writing
the specification in a way that describes a priori what happens.
That's hard, and it's harder in C++ where you get into all sorts of
niggling details when the objects in question have overloaded operators.
So the people writing the C++ standard just punted to C's version, on
the grounds that no one was clamoring for this anyway. The few who are
just have to roll their own.

> (In fact I did not know of this restriction of offsetof and I used offsetof for
> run-time offsets for many years without problems on many platforms.
> It was only last month I discovered that later versions of the gnu compiler
> refused to compile this code and that this is due to the limitation imposed by
> the standard.)

Newer compilers are trying to be helpful by pointing out potential
problems, but of course this breaks lots of stuff that "just worked"
in the past.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: sjhoweATdialDOTpipexDOTcom@eu.uu.net ("Stephen Howe")
Date: Thu, 9 Mar 2006 04:53:03 GMT
Raw View
> Now I have a function
>
> void f (int i) { ... }
>
> which needs to calculate the offset within s of b[i].

Okay. What about

offsetof(s,  b) + sizeof(s.b[0]) *  size_t(i);

Stephen Howe


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: F.Zwarts@KVI.nl ("Fred Zwarts")
Date: Thu, 9 Mar 2006 15:32:25 GMT
Raw View
"Hyman Rosen" <hyrosen@mail.com> wrote in message news:9fKPf.4785$FN1.3349@trndny04...
> Fred Zwarts wrote:
> The problem is that the standard has to say *something*. If it said
> "the result of offsetof is sometimes a constant expression and other
> times not" there would be quite a number of peeved users who would
> complain, because they would want to use constant expressions and
> they wouldn't be able to because the standard wasn't telling them
> when their code would be legal. So as I said, the problem is writing
> the specification in a way that describes a priori what happens.
> That's hard, and it's harder in C++ where you get into all sorts of
> niggling details when the objects in question have overloaded operators.
> So the people writing the C++ standard just punted to C's version, on
> the grounds that no one was clamoring for this anyway. The few who are
> just have to roll their own.

So maybe there should be another function (offsetof_rt) defined by the language,
so that run-time offsets can be calculated, without creating an object of the given
type.
My conclusion of the whole discussion is that C++ currently has no way to
calculate such an offset for a general case in a way that has a defined and
implementation independent result. So, I have to fall back to a work-around
that will work on most platforms (which probably is the macro definition
found in most implementations).

Fred.Zwarts.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: kuyper@wizard.net
Date: Fri, 10 Mar 2006 01:30:33 CST
Raw View
"Fred Zwarts" wrote:
.
> My conclusion of the whole discussion is that C++ currently has no way to
> calculate such an offset for a general case in a way that has a defined and
> implementation independent result.

Well, yes - the result is inherently implementation-dependent. The best
that you could hope for is "defined".  For the result to be
implementation-independent C++ would have to specify the exact sizes of
scalar types, and the layout of struct types. I don't think that's
likely to happen anytime soon.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: F.Zwarts@KVI.nl ("Fred Zwarts")
Date: Mon, 6 Mar 2006 16:15:46 GMT
Raw View
Consider the following definition:

typedef struct {
    int a;
    int b[100];
} s;

(This is just an example. In the real world my structs are more complex.)

Now I have a function

 void f (int i) { ... }

which needs to calculate the offset within s of b[i].

I used to use the offsetof macro for this purpose:

  offsetof (s, b[i])

For most compiler environments offsetof is defined as a macro as follows
in stddef.h:

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

and in these cases my function works as I expected..

However, I now have a new compiler which uses a built-in function instead of this macro.
A error message is generated at compile time for my use of offsetof because
this built-in function requires that the offset is a compile-time constant.
I understand that there is some discussion about the exact wording and interpretation
of the standard with respect to the constant requirement for offsetof.

My first question is what is the rationale behind this requirement in the C++ standard?
There clearly is a need for offsetof for offsets that are not constant.

My second question is what other method(s) the standard offers to calculate an offset that is
not a constant. (Not for this particular struct, but in the general case.)

Regards,
Fred.Zwarts.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]