Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature request] align attribute without value defaults to largest supported alignment. #18749

Open
dlangBugzillaToGithub opened this issue Jan 8, 2014 · 6 comments

Comments

@dlangBugzillaToGithub
Copy link

Iain Buclaw (@ibuclaw) reported this on 2014-01-08T08:55:15Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=11883

CC List

Description

Currently there are only two behaviours with align in struct fields/decls.

// Foo.bar.alignsize = STRUCTALIGN_DEFAULT
// Foo.sizeof = 6
struct Foo { short[3] bar; }

// Foo.bar.alignsize = 8
// Foo.sizeof = 8
struct Foo { align(8) short[3] bar; }

// Foo.bar.alignsize = STRUCTALIGN_DEFAULT
// Foo.sizeof = 6
struct Foo { align short[3] bar; }


This means that 'align' without a alignment value is redundant, so I propose an change to give it a more meaningful (and useful) semantic.  That is to tell the compiler to align a type to the maximum useful alignment for the target machine you are compiling for.  This matches the behaviour of gcc __attribute__((aligned)).


---
Whenever you leave out the alignment factor in an 'align' attribute specification, the compiler automatically sets the alignment for the type to the largest alignment that is ever used for any data type on the target machine you are compiling for. Doing this can often make copy operations more efficient, because the compiler can use whatever instructions copy the biggest chunks of memory when performing copies to or from the variables that have types that you have aligned this way.

Note that although you can ask the compiler to select a time-efficient alignment for a given type and then declare only individual stand-alone objects of that type, the compiler's ability to select a time-efficient alignment is primarily useful only when you plan to create arrays of variables having the relevant (efficiently aligned) type. If you declare or use arrays of variables of an efficiently-aligned type, then it is likely that your program also does pointer arithmetic (or subscripting, which amounts to the same thing) on pointers to the relevant type, and the code that the compiler generates for these pointer arithmetic operations is often more efficient for efficiently-aligned types than for other types.
--


In the example above, the 'align' would have this effect on the struct:

// Foo.bar.alignsize = ALIGNATTR_DEFAULT
// Foo.sizeof = 8
struct Foo { align short[3] bar; }

Without 'align' the size of the entire struct type is 6 bytes. The smallest power of two that is greater than or equal to that is 8, so the compiler sets the alignment for the entire struct type to 8 bytes.
@dlangBugzillaToGithub
Copy link
Author

andrej.mitrovich (@AndrejMitrovic) commented on 2014-01-08T09:26:57Z

align without an argument will re-set the alignment to default, which may be useful in some situations:

-----
struct Foo
{
align(8):
    short a;
    short b;
    short c;
align:
    short d;
}

void main()
{
    pragma(msg, Foo.a.offsetof);  // 0
    pragma(msg, Foo.b.offsetof);  // 8
    pragma(msg, Foo.c.offsetof);  // 16
    pragma(msg, Foo.d.offsetof);  // 18
}
-----

@dlangBugzillaToGithub
Copy link
Author

ibuclaw (@ibuclaw) commented on 2014-01-08T09:38:37Z

(In reply to comment #1)
> align without an argument will re-set the alignment to default, which may be
> useful in some situations:
> 
> -----
> struct Foo
> {
> align(8):
>     short a;
>     short b;
>     short c;
> align:
>     short d;
> }
> 

I feel that has less of a use case, especially when implementing C structs that use __attribute__((aligned)) in their code.

@dlangBugzillaToGithub
Copy link
Author

ibuclaw (@ibuclaw) commented on 2014-01-08T09:39:06Z

https://github.com/D-Programming-Language/dmd/pull/3073

@dlangBugzillaToGithub
Copy link
Author

ibuclaw (@ibuclaw) commented on 2014-01-08T09:52:57Z

(In reply to comment #2)
> 
> I feel that has less of a use case, especially when implementing C structs that
> use __attribute__((aligned)) in their code.

Such as libunwind (used by GDC).  Where there is no handy way to say that we want:

1) _Unwind_Exception to be aligned to __attribute__((aligned))
2) To pad out gdc's own unwind exception struct so that the Object thrown in D comes immediately before the generic exception header.

@dlangBugzillaToGithub
Copy link
Author

ibuclaw (@ibuclaw) commented on 2014-01-09T06:27:04Z

(In reply to comment #2)
> (In reply to comment #1)
> > align without an argument will re-set the alignment to default, which may be
> > useful in some situations:
> > 
> > -----
> > struct Foo
> > {
> > align(8):
> >     short a;
> >     short b;
> >     short c;
> > align:
> >     short d;
> > }
> > 
> 
> I feel that has less of a use case, especially when implementing C structs that
> use __attribute__((aligned)) in their code.

And if you really insist, perhaps we should introduce brace syntax { } to align, just like all other attribute declarations.

@dlangBugzillaToGithub
Copy link
Author

bugzilla (@WalterBright) commented on 2014-01-12T11:21:56Z

The point of 'align' without argument is to set the alignment to match the host C compiler's, i.e. to use the default. It is needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant