This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: using offsetof with g++
Joe Buck <jbuck@synopsys.com> writes:
| On Thu, Nov 06, 2003 at 10:09:23AM -0800, Doug Evans wrote:
| > version = 3.3.2, i386-linux
| >
| > cp/typeck.c has this:
| >
| > /* Complain about other invalid uses of offsetof, even though they will
| > give the right answer. ...
|
| ...
|
| > No doubt there's a language citation for why this exists,
| > but I wonder if you guys would be amenable to adding an option
| > to turn this check off. Is there some expectation that "the right answer"
| > will no longer be possible some day?
|
| It seems to me that there are four categories:
|
| 1) Those cases where ISO C++ specifies what the answer is.
|
| 2) Those cases where any reasonable implementation (and all
| implementations we know of) give the right answer, but ISO
| C++ says "undefined".
|
| 3) Those cases where we know that g++ will give the right answer,
| but we can't be sure of other possible implementations.
|
| 4) Those cases where use of offsetof() is nonsense, since the offset
| is not even constant.
|
| Example of case 2: the object is a POD, but then we add one or more
| constructors to initialize the fields. The normal offsetof() will
| Just Work (even if a language lawyer might point out that it's now
| legally allowed to implement the class in some strange new way).
|
| The simple single inheritance cases that you show are probably in case
| 2 (since I know of no implementation that doesn't lay out the derived
| classes in one chunk).
|
| Example of case 4: asking for the offset of a member of a virtual
| base class from a derived object, where we only have a pointer or
| reference to the derived object. The offsetof macro will compute
| something, but using the result to access the member of a real object
| might crash.
|
| Some other folks might be able to come up with case 3 examples.
I don't know where you put my favorite example that involve
references:
int i;
struct A {
int& r;
A() : r(i) { }
};
int main()
{
cout << offsetof(A, r) << endl;
}
| > While a warning in and of itself isn't fatal, consider -Werror.
| > Also consider a c++ application that does dynamic compilation.
| > Any suggestions for how to get the offsetof various fields
| > that I can use in the code generator?
|
| If we did permit disabling the warning, should we distinguish between the
| cases above? One could argue that we're just being anal-retentive
| for warning about case 2 when the user didn't specify -pedantic.
We do already have a flag to silent the warning.
I'm sure Matt remembers that when having a dinner in Kona with Bjarne
and others, I brought this issue but could not give any convinving
arguments as answers to the following basic question
Why do you want to take the offsetof a non-POD?
(I know Matt gave at least two reasons but I can't recall; I just
remember mine was not convincing enough). The reason I brought up
that issue is that the C++ evolution working group has a suggestion to
allow arithmetic on pointer to members and generic pointer to members.
If those were allowed, the notion of offsetof for non-POD will
essentially become moot.
-- Gaby