From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10029 invoked by alias); 21 Apr 2003 17:25:38 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 10017 invoked from network); 21 Apr 2003 17:25:37 -0000 Received: from unknown (HELO mail.jlokier.co.uk) (81.29.64.88) by sources.redhat.com with SMTP; 21 Apr 2003 17:25:37 -0000 Received: from mail.jlokier.co.uk (localhost [127.0.0.1]) by mail.jlokier.co.uk (8.12.8/8.12.8) with ESMTP id h3LHPbjF016050; Mon, 21 Apr 2003 18:25:37 +0100 Received: (from jamie@localhost) by mail.jlokier.co.uk (8.12.8/8.12.8/Submit) id h3LHPbYP016048; Mon, 21 Apr 2003 18:25:37 +0100 Date: Mon, 21 Apr 2003 18:14:00 -0000 From: Jamie Lokier To: Richard Kenner Cc: aoliva@redhat.com, gcc-patches@gcc.gnu.org, gcc@gcc.gnu.org Subject: Re: DATA_ALIGNMENT vs. DECL_USER_ALIGNMENT Message-ID: <20030421172537.GA15952@mail.jlokier.co.uk> References: <10304211651.AA29704@vlsi1.ultra.nyu.edu> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <10304211651.AA29704@vlsi1.ultra.nyu.edu> User-Agent: Mutt/1.4.1i X-SW-Source: 2003-04/txt/msg00996.txt.bz2 Richard Kenner wrote: > So if you turn: > > T i __attribute__((align(2))); > T j __attribute__((align(2))); > > into > > typedef T T2 __attribute__((align(2))); > T2 i, j; > > you say we could get different code? > > I say so, yes. > > And the reason is as I said: you specify alignment for a type both for > interface and efficiency reasons, but for an object only for the latter. > So there is a difference in meaning between these two constructs. So, starting from the second (typedef) sample, if I write: __typeof__(i) * ptr = &i; use (*ptr); That should be equivalent to: T2 * ptr = &i; use (*ptr); The code for `use' may assume that the pointer has at least an alignment of 2, i.e. the least significant bit of the pointer is zero? That seems to imply that `i' must have an alignment of at least 2, if it is declared using the typedef. This is also true if `i' is declared with object alignment, as in the first code sample, as `T i __attribute__ ((aligned (2)))' as well. So what is the difference? Robert Dewar, on behalf of Ada, seems to think that the object alignment specification implies a _maximum_ alignment as well as a minimum. For fields in structures this is relevant. But for data variables? I have always expected that a user-specific alignment attribute can only increase the alignment of a type or object, not decrease it. After all, an object with alignment 8 *is* an object with alignment 4, for pointer dereferences and arithmetic purposes. >From a C programming point of view, I tend to think of the pointer address constraint as the whole reason for specifying alignment. (If I want to control structure layout, I'll use `__attribute__((packed))'). And, for this, any reason for a type or object to have an alignment should only be able to _increase_ the value. But now I see that decreasing alignment is sometimes useful, because that influences how data is packed in memory, which is useful in some data structures and things like variables in special sections. It seems that in Ada, this "exact alignment" constraint is a language requirement. (Is this correct, Robert?) When there is a mechanism for limiting the alignment of an object to something below it's natural alignment, this affects the correctness of compiler-generated code which dereferences pointers to it, and when performing arithmetic with those pointers.dereference that type This suggests two kinds of user alignment constraint: __attribute__((aligned(x))) - forces type or object or field to have AT LEAST alignment x __attribute__((exactly_aligned(x))) - forces type or object or field to have EXACTLY alignment x, overriding natural alignment constraints. Both of these should inherit from types to objects and fields, AND they inherit from objects and fields back to types, when the user does `__typeof__' or uses the address-of operator (`&' in C). In other words, assuming that the `exactly_aligned' attribute has the qualities that I belive Robert thinks `aligned' should have for objects: /* sizeof(int) == __alignof__(int) == 4. */ typedef int T __attribute_((exactly_aligned(2))); int x __attribute_((exactly_aligned(2))); int __attribute((exactly_aligned(2))) * px1 = &x; /* Correct. */ T * px2 = &x; /* Correct. */ int * px3 = &x; /* Type error (just a warning?). */ T y1 = *px1; /* Fine, special code emitted by compiler. */ T y3 = *px3; /* Crashes due to access alignment fault... */ Whereas, if you replace each occurence of `exactly_aligned' with `aligned' in the above, there will be no access alignment fault (or compile time type error, whichever is implemented). -- Jamie