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

offsetof in C++

40 views
Skip to first unread message

jacobnavia

unread,
Jul 21, 2017, 6:25:57 AM7/21/17
to
Hi
I have to deal with this code:
93// given a pointer to w->m_chunk (where w is a CDBStringWrapper)
return w.
94 static CDBStringWrapper* wrapperFromChunk(StringChunk const* c) {
95 return (CDBStringWrapper*)((char*)c -
offsetof(CDBStringWrapper, m_chunk));
96 }

I have read about all kinds of warnings workaround and why the work
around do not work about this.

What would be the replacement of "offsetof" in C++

P.S. This code compiled OK for around 12 years.

Öö Tiib

unread,
Jul 21, 2017, 6:45:50 AM7/21/17
to
Is that CDBStringWrapper standard layout type?
Can you post what you complain about 'offsetof', what is expected behavior
and what is actual behavior?

Melzzzzz

unread,
Jul 21, 2017, 6:57:21 AM7/21/17
to
Well offsetof work only on POD structures. If CDBStringWrapper is not
POD, you are out of luck...

--
press any key to continue or any other to quit...

Alf P. Steinbach

unread,
Jul 21, 2017, 7:34:37 AM7/21/17
to
On 21.07.2017 12:25, jacobnavia wrote:
> Hi
> I have to deal with this code:
> 93// given a pointer to w->m_chunk (where w is a CDBStringWrapper)
> return w.
> 94 static CDBStringWrapper* wrapperFromChunk(StringChunk const* c) {
> 95 return (CDBStringWrapper*)((char*)c -
> offsetof(CDBStringWrapper, m_chunk));
> 96 }
>
> I have read about all kinds of warnings workaround and why the work
> around do not work about this.
>
> What would be the replacement of "offsetof" in C++

It's still `offsetof`.

It's limited to POD types.


> P.S. This code compiled OK for around 12 years.

In general, although the compiler may complain, there won't be a problem
with offsets being dynamic unless some virtual base class is involved,
and there won't be a problem with nullpointers dereferenced at compile
time, so if just the compiler optimizes the expression to compile time
constant you can (safely, but not formally) do things like this:


struct Blah
{
int x;
int y;
virtual ~Blah() {}
Blah( int a, int b ): x{a}, y{b} {}
};

#include <stddef.h> // offsetof
#include <stdio.h>
using Byte = unsigned char;

namespace my{
using Size = ptrdiff_t;

auto dummy() -> Blah* { return nullptr; }

auto y_offset()
-> Size
{
return
reinterpret_cast<Byte*>( &(dummy()->y) )
- reinterpret_cast<Byte*>( dummy() );
}
} // namespace my

auto main()
-> int
{
Blah const o{ 111, 222 };

int const* const py = &o.y;

Blah const* const po =
reinterpret_cast<Blah const*>(
reinterpret_cast<Byte const*>( py ) - //offsetof( Blah, y )
my::y_offset()
);
printf( "%d %d\n", po->x, po->y );
}


Cheers &/ hth.,

- Alf

Ben Bacarisse

unread,
Jul 21, 2017, 7:40:30 AM7/21/17
to
jacobnavia <ja...@jacob.remcomp.fr> writes:

> Hi
> I have to deal with this code:
> 93// given a pointer to w->m_chunk (where w is a CDBStringWrapper) return w.
> 94 static CDBStringWrapper* wrapperFromChunk(StringChunk const* c) {
> 95 return (CDBStringWrapper*)((char*)c -
> offsetof(CDBStringWrapper, m_chunk));
> 96 }
>
> I have read about all kinds of warnings workaround and why the work
> around do not work about this.
>
> What would be the replacement of "offsetof" in C++

What's going wrong? Are the conditions required of offsetof being met?
Is the type a standard-layout class?

> P.S. This code compiled OK for around 12 years.

What's the compiler's error message?

--
Ben.

jacobnavia

unread,
Jul 21, 2017, 8:19:39 AM7/21/17
to
DBBaseString.h: In static member function ‘static CDBStringWrapper*
CDBStringWrapper::wrapperFromChunk(const StringChunk*)’:
DBBaseString.h:95:66: error: expected primary-expression before ‘,’ token

jacobnavia

unread,
Jul 21, 2017, 8:20:27 AM7/21/17
to
Le 21/07/2017 à 13:40, Ben Bacarisse a écrit :
> What's the compiler's error message?
DBBaseString.h: In static member function ‘static CDBStringWrapper*
CDBStringWrapper::wrapperFromChunk(const StringChunk*)’:
DBBaseString.h:95:66: error: expected primary-expression before ‘,’ token

jacobnavia

unread,
Jul 21, 2017, 8:33:27 AM7/21/17
to
MY FAULT! Excuse me all.

The problem is that (somehow) cstddef.h wasn't getting included.

How could this compile OK for so many years?

Well, somebody has thought that it would be a good idea to optimize out the:

#include <cstddef.h>

in the latest version!

He replaced it by the much faster code:

6 #if !defined(_SIZE_T_DEFINED)
7 #ifdef _64BIT
8 #if defined(_WIN64)
9 typedef unsigned __int64 size_t;
10 #else // defined(_WIN64)
11 typedef unsigned long long size_t;
12 #endif // defined(_WIN64)
13 #else
14 typedef unsigned int size_t;
15 #endif
16 #define _SIZE_T_DEFINED
17 #endif // !defined(_SIZE_T_DEFINED)

CLEVER isn't it?


Bad luck! stddef.h defines OTHER THINGS besides size_t!!!!!

Excuses to all.

jacob

Manfred

unread,
Jul 21, 2017, 11:55:13 AM7/21/17
to
On 7/21/2017 2:33 PM, jacobnavia wrote:
> Well, somebody has thought that it would be a good idea to optimize out
> the:
>
> #include <cstddef.h>
probably either <stddef.h> or <cstddef>

jacobnavia

unread,
Jul 21, 2017, 11:58:08 AM7/21/17
to
Yes, it is cstddef. I am so fed up I can't think any more.

Why "optimize" things that way?

DAMM IT!

Manfred

unread,
Jul 21, 2017, 12:08:39 PM7/21/17
to
Because some are so much more clever than others, that they can't resist
the temptation to show it :D

Öö Tiib

unread,
Jul 21, 2017, 1:47:33 PM7/21/17
to
Such things are indicating that some in team have nothing to.
Can't you resolve it within team? Some "git blame" or the like to see the
author of that change and why it was made and then see reviewer who
accepted the pull request.
0 new messages