From owner-freebsd-standards@FreeBSD.ORG Fri Apr 1 15:50:33 2005 Return-Path: Delivered-To: freebsd-standards@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id E8EAB16A4CE for ; Fri, 1 Apr 2005 15:50:33 +0000 (GMT) Received: from mailout1.pacific.net.au (mailout1.pacific.net.au [61.8.0.84]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4FDE243D3F for ; Fri, 1 Apr 2005 15:50:33 +0000 (GMT) (envelope-from bde@zeta.org.au) Received: from mailproxy2.pacific.net.au (mailproxy2.pacific.net.au [61.8.0.87])j31FoSA6030988; Sat, 2 Apr 2005 01:50:28 +1000 Received: from katana.zip.com.au (katana.zip.com.au [61.8.7.246]) j31FoQMq025649; Sat, 2 Apr 2005 01:50:27 +1000 Date: Sat, 2 Apr 2005 01:50:26 +1000 (EST) From: Bruce Evans X-X-Sender: bde@delplex.bde.org To: =?iso-8859-1?q?Dag-Erling_Sm=F8rgrav?= In-Reply-To: <86br8yr118.fsf@xps.des.no> Message-ID: <20050402012011.K24853@delplex.bde.org> References: <86br8yr118.fsf@xps.des.no> MIME-Version: 1.0 Content-Type: MULTIPART/MIXED; BOUNDARY="0-137614039-1112370626=:24853" cc: standards@freebsd.org Subject: Re: offsetof X-BeenThere: freebsd-standards@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Standards compliance List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 Apr 2005 15:50:34 -0000 This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. --0-137614039-1112370626=:24853 Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed Content-Transfer-Encoding: QUOTED-PRINTABLE On Fri, 1 Apr 2005, [iso-8859-1] Dag-Erling Sm=F8rgrav wrote: > I noticed that our definition of offsetof (in ) is as > follows: > > #define __offsetof(type, field) ((size_t)(&((type *)0)->field)) > > This definition is gratuitously unportable (it assumes that a null > pointer is all-bits-zero). A better definition would be the > following: > > #define __offsetof(type, field) \ > ((size_t)((char *)&((type *)0)->field - (char *)(type *)0)) Both are unportable, so FreeBSD uses the simplest one. In fact, the second one is more unportable since it is more complicated. In both, we don't assume anything about the representation of the null pointer; we assume that the undefined behaviour for "&((type *)0)->field" gives a useful value. This value can be the unrelated to the representation of "(type *)0", so it can be useful even if "(type *)0" isn't all-bits-0. The first version assumes that the useful value is the final result after further conversions. The second version assumes that the undefined behaviour of subtracting a null pointer from the useful value gives another useful value that is final value after further conversions. To be ungratuitously unportable, the definition needs to be machine- and compiler-dependent. We don't need the complications for this yet. It would be mainly compiler-dependent. Sample definitions: gcc: same as FreeBSD except for spelling TenDRA: #pragma token PROC { STRUCT s, TYPE t, MEMBER t : s : m |\ TYPE s, MEMBER s : m } EXP const : size_t : offsetof # ansi.stddef.offs= etof Bruce --0-137614039-1112370626=:24853--