#include <cstddef>
...
template<class T> struct alignment
{
struct lump
{
unsigned char pad;
T t;
};
static const std::size_t value = offsetof(lump, t);
};
-- Mat.
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
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
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" <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.
> > {
> > 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.
>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.
> > > 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" <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.
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).