Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

offsetof(type, member constant expression?

4 views
Skip to first unread message

Mathew Hendry

unread,
Mar 28, 2002, 1:35:21 PM3/28/02
to
Is the result of offsetof(type, member) a constant expression in C++? e.g.
would it be okay to use offsetof as below

#include <cstddef>
...
template<class T> struct alignment
{
struct lump
{
unsigned char pad;
T t;
};
static const std::size_t value = offsetof(lump, t);
};

-- Mat.

Victor Bazarov

unread,
Mar 28, 2002, 1:43:17 PM3/28/02
to
"Mathew Hendry" <mathew...@hotmail.com> wrote...


C++ puts no special limitation on the constness of the result of
offsetof macro. I don't have the C Standard handy, just look at
how it is defined in <cstddef>. It is likely to be a compile-
time expression (like sizeof, e.g.), so it must be OK to initialise
a constant with it.

Victor
--
Please remove capital A's from my address when replying by mail


Shane McDaniel

unread,
Mar 28, 2002, 2:08:12 PM3/28/02
to

unless your struct is going to dynamically change its structure during
runtime (which I think would go against the standard) then this call to
offsetof() would always result in the same answer regaurdless of where
it was executed.

-shane

Ruslan Abdikeev

unread,
Mar 28, 2002, 2:17:55 PM3/28/02
to
"Mathew Hendry" <mathew...@hotmail.com> wrote in message
news:u6o6aughfngkljbt3...@4ax.com...

It is guaranteed at least in C99:
"... and offsetof( type, member-designator ) which
expands to an integer constant expression that has
type size_t..." (C99, 7.17/3)

C++98 is based on C90, but I hardly believe C90
defined offsetof() other way.

Sincerely,

Ruslan Abdikeev
Brainbench MVP for Visual C++
http://www.brainbench.com

Mathew Hendry

unread,
Mar 28, 2002, 2:20:46 PM3/28/02
to
On Thu, 28 Mar 2002 18:43:17 GMT, "Victor Bazarov"
<vAba...@dAnai.com> wrote:

>"Mathew Hendry" <mathew...@hotmail.com> wrote...
>> Is the result of offsetof(type, member) a constant expression in C++? e.g.
>> would it be okay to use offsetof as below
>>
>> #include <cstddef>
>> ...
>> template<class T> struct alignment
>> {
>> struct lump
>> {
>> unsigned char pad;
>> T t;

Sorry about the dodgy formatting there, some evil tabs sneaked in
somehow. :)

>> };
>> static const std::size_t value = offsetof(lump, t);
>> };
>
>C++ puts no special limitation on the constness of the result of
>offsetof macro. I don't have the C Standard handy, just look at
>how it is defined in <cstddef>. It is likely to be a compile-
>time expression (like sizeof, e.g.), so it must be OK to initialise
>a constant with it.

I don't have the C standard to hand either, but according to

http://www.dinkumware.com/htm_cpl/stddef.html#offsetof

offsetof does indeed yield a constant expression.

The purpose of the template is to figure out type alignment
requirements for use in an allocator. AFAICT it's safe and portable.

-- Mat.

Alexander Terekhov

unread,
Mar 28, 2002, 3:08:40 PM3/28/02
to

Ruslan Abdikeev wrote:
>
> "Mathew Hendry" <mathew...@hotmail.com> wrote in message
> news:u6o6aughfngkljbt3...@4ax.com...
> > Is the result of offsetof(type, member) a constant expression in C++? e.g.
> > would it be okay to use offsetof as below
> >
> > #include <cstddef>
> > ...
> > template<class T> struct alignment
^^^^^^^

> > {
> > struct lump
> > {
> > unsigned char pad;
> > T t;
> > };
> > static const std::size_t value = offsetof(lump, t);
> > };
> >
>
> It is guaranteed at least in C99:
> "... and offsetof( type, member-designator ) which
> expands to an integer constant expression that has
> type size_t..." (C99, 7.17/3)
>
> C++98 is based on C90, but I hardly believe C90
> defined offsetof() other way.

"ISO/IEC 14882:1998(E) Š ISO/IEC
18.1 Types 18 Language support library
....
The macro offsetof accepts a restricted set of type
arguments in this International Standard. type
shall be a POD structure or a POD union (clause 9).
....
[diff.offsetof] C.2.4.1 Macro offsetof(type, memberdesignator)
1 The macro offsetof, defined in <cstddef>, accepts a restricted
set of type arguments in this International Standard. 18.1
describes the change."

regards,
alexander.

Mathew Hendry

unread,
Mar 28, 2002, 3:45:01 PM3/28/02
to
On Thu, 28 Mar 2002 21:08:40 +0100, Alexander Terekhov
<tere...@web.de> wrote:

>Ruslan Abdikeev wrote:
>>
>> "Mathew Hendry" <mathew...@hotmail.com> wrote in message
>> news:u6o6aughfngkljbt3...@4ax.com...
>>

>> > #include <cstddef>
>> > ...
>> > template<class T> struct alignment
> ^^^^^^^
>
>> > {
>> > struct lump
>> > {
>> > unsigned char pad;
>> > T t;
>> > };
>> > static const std::size_t value = offsetof(lump, t);
>> > };
>> >
>

>"ISO/IEC 14882:1998(E) Š ISO/IEC
> 18.1 Types 18 Language support library
> ....
> The macro offsetof accepts a restricted set of type
> arguments in this International Standard. type
> shall be a POD structure or a POD union (clause 9).
> ....
> [diff.offsetof] C.2.4.1 Macro offsetof(type, memberdesignator)
> 1 The macro offsetof, defined in <cstddef>, accepts a restricted
> set of type arguments in this International Standard. 18.1
> describes the change."

Ah, that breaks my idea. And BTW, VC7 *really* doesn't like it if I
try it with a non-POD type

...
int main(void) {
std::cout << alignment<std::vector<int> >::value << '\n';
return 0;
}
...

E:\Source\align>cl /nologo align.cpp
align.cpp
align.cpp(11) : fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 2844)
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more
information

Nice. :)

-- Mat.

Ruslan Abdikeev

unread,
Mar 28, 2002, 3:52:02 PM3/28/02
to
"Alexander Terekhov" <tere...@web.de> wrote in message news:3CA37848...@web.de...

> Ruslan Abdikeev wrote:
> > "Mathew Hendry" <mathew...@hotmail.com> wrote in message
> > news:u6o6aughfngkljbt3...@4ax.com...

> > > Is the result of offsetof(type, member) a constant expression in C++?

Ouch, I have read the question,

> > > e.g.
> > > would it be okay to use offsetof as below
> > >
> > > #include <cstddef>
> > > ...
> > > template<class T> struct alignment
> ^^^^^^^

but did not notice THAT.
My apologies.

>
> > > {
> > > struct lump
> > > {
> > > unsigned char pad;
> > > T t;
> > > };
> > > static const std::size_t value = offsetof(lump, t);
> > > };
> > >
> >
> > It is guaranteed at least in C99:
> > "... and offsetof( type, member-designator ) which
> > expands to an integer constant expression that has
> > type size_t..." (C99, 7.17/3)
> >
> > C++98 is based on C90, but I hardly believe C90
> > defined offsetof() other way.
>

> The macro offsetof accepts a restricted set of type
> arguments in this International Standard. type
> shall be a POD structure or a POD union (clause 9).

Thank you, Alexander.
I stand corrected.

Ruslan


Mathew Hendry

unread,
Mar 29, 2002, 6:42:05 AM3/29/02
to
Alexander Terekhov <tere...@web.de> wrote:

: > "Mathew Hendry" <mathew...@hotmail.com> wrote in message
: > news:u6o6aughfngkljbt3...@4ax.com...

: > >
: > > #include <cstddef>


: > > ...
: > > template<class T> struct alignment
: ^^^^^^^
: > > {
: > > struct lump
: > > {
: > > unsigned char pad;
: > > T t;
: > > };
: > > static const std::size_t value = offsetof(lump, t);

: > > };
:
: "ISO/IEC 14882:1998(E) Š ISO/IEC


: 18.1 Types 18 Language support library
: ....
: The macro offsetof accepts a restricted set of type
: arguments in this International Standard. type
: shall be a POD structure or a POD union (clause 9).
: ....
: [diff.offsetof] C.2.4.1 Macro offsetof(type, memberdesignator)
: 1 The macro offsetof, defined in <cstddef>, accepts a restricted
: set of type arguments in this International Standard. 18.1
: describes the change."

What is the rationale for this limitation? Is it a safety issue - programs
should not be able to determine the layout of complex classes - or are there
difficulties with implementing it for non-POD types? (The VC7 internal
compiler error I mentioned in another post suggests the latter; it also
happens with VC6, but gcc handles it without complaint. Since the above
quotations impose a "shall", I think a diagnostic should be generated).

And, since I can't do it this way, is there some other portable way of
finding the alignment requirements for a given class?

-- Mat.

Victor Bazarov

unread,
Mar 29, 2002, 1:01:37 PM3/29/02
to
"Mathew Hendry" <mathew...@hotmail.com> wrote...
> Alexander Terekhov <tere...@web.de> wrote:
>
> : [...]

> : "ISO/IEC 14882:1998(E) Š ISO/IEC
> : 18.1 Types 18 Language support library
> : ....
> : The macro offsetof accepts a restricted set of type
> : arguments in this International Standard. type
> : shall be a POD structure or a POD union (clause 9).
> : ....
> : [diff.offsetof] C.2.4.1 Macro offsetof(type, memberdesignator)
> : 1 The macro offsetof, defined in <cstddef>, accepts a restricted
> : set of type arguments in this International Standard. 18.1
> : describes the change."
>
> What is the rationale for this limitation? Is it a safety issue - programs
> should not be able to determine the layout of complex classes - or are
there
> difficulties with implementing it for non-POD types?

Both. And better ask in comp.std.c++ -- they discuss the "why"
aspects of the Standard.

> (The VC7 internal
> compiler error I mentioned in another post suggests the latter; it also
> happens with VC6, but gcc handles it without complaint. Since the above
> quotations impose a "shall", I think a diagnostic should be generated).
>
> And, since I can't do it this way, is there some other portable way of
> finding the alignment requirements for a given class?

You just mentioned the safety -- "should not be able to determine
the layout" means "no portable way to find the alignment". In a
correctly designed and written program there is _no_ need to know
the layout or the alignment requirements.

Now, consider member functions. What should the offsetof produce?
What should it produce if the class has virtual functions? In C
you have a very simple aggregation of data. In C++ it's much more
complex. If you give me an example where you _really_ need that
macro, I can probably find a better way to handle things using C++
means (pointers to members, for example).

0 new messages