digitalmars.D - The great inapplicable attribute debate
- Stewart Gordon (50/50) Apr 12 2009 It's cropped up on a number of occasions. And again in the comments on
- BCS (5/13) Apr 12 2009 If I remembered that this one even exists, I might use it.
- Nick Sabalausky (8/21) Apr 12 2009 I'm kind of on the fence about whether (ii) or (iii) should be allowed. ...
- grauzone (5/27) Apr 12 2009 I use all three all the time. It's a nice mini feature of D. No reason
- BCS (3/10) Apr 12 2009 complexity re the OP's point, not just in general. if only (i) is allowe...
- Nick Sabalausky (24/54) Apr 12 2009 Absolutely. I think it boils down to this: If something seems to work, i...
- Kagamin (2/10) Apr 13 2009 Such mood was always in the spec: "AlignAttribute is ignored when applie...
- Frits van Bommel (4/16) Apr 13 2009 I never saw that before. So it doesn't work for class members? And it wo...
- Tomas Lindquist Olsen (14/32) Apr 13 2009 that the
- Denis Koroskin (5/38) Apr 13 2009 You are kind of contradict yourself.
- Tomas Lindquist Olsen (11/54) Apr 13 2009 nd
- Stewart Gordon (15/23) Apr 13 2009 http://www.digitalmars.com/d/1.0/class.html
- Frits van Bommel (29/50) Apr 13 2009 Right, forgot about that bit. Probably because AFAIK no D compiler actua...
-
Stewart Gordon
(13/40)
Apr 13 2009
- Don (6/34) Apr 14 2009 Not so, the alignment of each member should be respected. Most
- Stewart Gordon (7/14) Apr 14 2009 But the offset of a union member is always zero. So what would this do?
- Frits van Bommel (6/21) Apr 14 2009 It should make sure the union is aligned appropriately in a containing s...
- Stewart Gordon (11/27) Apr 14 2009 But alignment of a member within a structure and alignment of the whole
- Don (6/36) Apr 14 2009 I'm not sure why you think unions are so different to structs. They are
- Stewart Gordon (7/20) Apr 14 2009 I still don't know what you mean.
- Christopher Wright (9/34) Apr 14 2009 You know ahead of time that you're going to use this union everywhere
- Don (13/35) Apr 15 2009 You're acting as if there's a big difference between unions and structs,...
- Stewart Gordon (28/58) Apr 15 2009 No, you have to add to that the differences inherited from C. Moreover,...
- Don (24/94) Apr 16 2009 In the compiler, struct and union share almost all of their code.
- Tomas Lindquist Olsen (20/121) Apr 16 2009 ,
- Christopher Wright (3/28) Apr 14 2009 Or the least common multiple, assuming that align accepts arguments that...
- Frits van Bommel (9/15) Apr 14 2009 I have never seen "alignment" used to describe addresses at a multiple o...
- Michel Fortin (14/18) Apr 14 2009 Interesting observation.
- Frits van Bommel (25/41) Apr 14 2009 Some problems I see with this:
It's cropped up on a number of occasions. And again in the comments on http://d.puremagic.com/issues/show_bug.cgi?id=2830 http://d.puremagic.com/issues/show_bug.cgi?id=1441 which are essentially the same as each other. The basic matter of debate is: If an attribute is applied to something to which it is not applicable, should it be an error, silently ignored or what? There are a number of cases to consider: (a) Attributes that state what is already implied by the context. For example, module-level functions are effectively both static and final. (b) Attributes that don't make sense in the context. For example, trying to apply scope to a function. (c) Attributes that make sense in the context but are nonetheless not actually applied. The issue brought up in the above bug reports is an example - actual compiler behaviour even _contradicts_ the fact that a protection attribute has been specified. One recent comment referred to inapplicable attributes generally as "'pointless' attributes". This may be a valid label for (a), but certainly not (b) or (c). At the moment, the problem seems to be that the compiler is silently ignoring many cases of (a), (b) and (c) alike. Some people argue that the spec doesn't forbid such use of inapplicable attributes explicitly, and so the compiler's treatment of these cannot be called a bug. I argue that this isn't right. Nothing I've managed to find in the spec states or implies that such obviously wrong code is allowed. So, by applying common sense, one would conclude that it isn't allowed. Perhaps what complicates matters further is that D has three ways of specifying attributes: (i) as part of the declaration itself (ii) in a block delimited by { } (iii) with a colon to apply to everything that follows until the end of the scope It would be annoying to have to avoid (iii) just because you want to declare something of a kind to which the attribute is inapplicable later in the file. This may also apply to some degree to (ii), but any use of an inapplicable attribute (at least of case (b) or (c)) by (i) is bound to be a mistake. There are also attributes, such as align and (I think) extern, for which applying to a compound type is equivalent to applying to all of its members. This should be allowed wherever it makes sense to the context, since it would be annoying (for example) to be prevented from declaring an alignment on a struct as a whole just because it contains functions. Basically, what we need to do is: - Eradicate all cases of (c), fixing it so that the attribute actually works in such cases. - Make sure all cases of (b) generate a compile error when used by (i). - Define some clear rules on when an attribute may be used by (ii) or (iii) if it is inapplicable to some of the entities to which the programmer has tried to apply it. Comments? Stewart.
Apr 12 2009
Hello Stewart,Perhaps what complicates matters further is that D has three ways of specifying attributes: (i) as part of the declaration itselfI more or less only use this.(ii) in a block delimited by { }If I remembered that this one even exists, I might use it.(iii) with a colon to apply to everything that follows until the end of the scopeI'd be just tickled if this one were just dropped. Just my $0.02 because that might make things less complex.
Apr 12 2009
"BCS" <none anon.com> wrote in message news:a6268ff4a7a8cb89c641dc84ac news.digitalmars.com...Hello Stewart,I'm kind of on the fence about whether (ii) or (iii) should be allowed. I haven't used (iii) since I was using C/C++ regularly (ie, almost 10 years ago). But I think the only real reason I switched from (iii) to (i) was of (i), but I keep debating with myself about occasional usage of (ii) or (iii).Perhaps what complicates matters further is that D has three ways of specifying attributes: (i) as part of the declaration itselfI more or less only use this.(ii) in a block delimited by { }If I remembered that this one even exists, I might use it.(iii) with a colon to apply to everything that follows until the end of the scopeI'd be just tickled if this one were just dropped. Just my $0.02 because that might make things less complex.
Apr 12 2009
BCS wrote:Hello Stewart,I use all three all the time. It's a nice mini feature of D. No reason to remove it. And if you want to remove complexity, start with the bigger chunks of the D language.Perhaps what complicates matters further is that D has three ways of specifying attributes: (i) as part of the declaration itselfI more or less only use this.(ii) in a block delimited by { }If I remembered that this one even exists, I might use it.(iii) with a colon to apply to everything that follows until the end of the scopeI'd be just tickled if this one were just dropped. Just my $0.02 because that might make things less complex.
Apr 12 2009
Hello grauzone,BCS wrote:complexity re the OP's point, not just in general. if only (i) is allowed then there isn't (much of) a case for allowing inapplicable attribute (IMHO).Just my $0.02 because that might make things less complex.And if you want to remove complexity, start with the bigger chunks of the D language.
Apr 12 2009
"Stewart Gordon" <smjg_1998 yahoo.com> wrote in message news:grtr90$1hlh$1 digitalmars.com...It's cropped up on a number of occasions. And again in the comments on http://d.puremagic.com/issues/show_bug.cgi?id=2830 http://d.puremagic.com/issues/show_bug.cgi?id=1441 which are essentially the same as each other. The basic matter of debate is: If an attribute is applied to something to which it is not applicable, should it be an error, silently ignored or what? There are a number of cases to consider: (a) Attributes that state what is already implied by the context. For example, module-level functions are effectively both static and final. (b) Attributes that don't make sense in the context. For example, trying to apply scope to a function. (c) Attributes that make sense in the context but are nonetheless not actually applied. The issue brought up in the above bug reports is an example - actual compiler behaviour even _contradicts_ the fact that a protection attribute has been specified. [snip] Perhaps what complicates matters further is that D has three ways of specifying attributes: (i) as part of the declaration itself (ii) in a block delimited by { } (iii) with a colon to apply to everything that follows until the end of the scope [snip] Basically, what we need to do is: - Eradicate all cases of (c), fixing it so that the attribute actually works in such cases. - Make sure all cases of (b) generate a compile error when used by (i). - Define some clear rules on when an attribute may be used by (ii) or (iii) if it is inapplicable to some of the entities to which the programmer has tried to apply it.Absolutely. I think it boils down to this: If something seems to work, it should work as expected. Things should either just "work" or "not work". _Never_ "it works, but does something completely different". I think this ticket I filed might also be another case of the same issue: http://d.puremagic.com/issues/show_bug.cgi?id=2775 I've never even looked to see if the language definition explicitly allows/forbids/doesn't-address using "private" on templates/structs/classes/unions. But for such a basic and conceptually simple language feature, I shouldn't even need to. Don't force me to be a language lawyer to use such simple things properly: If I stick "private" in front of something, and the compiler *accepts* it, it should "just f*^&*%^* work". If for some bizarre reason private templates/structs/classes/unions aren't supposed to be allowed (which I *really* hope is not the case), then dagnabbit, the compiler needs to speak up. After all, it is the role of the compiler to raise an error when the programmer tries to do something that isn't allowed, and not to just silently make up some alternative behavior (if I wanted to put up with that kind of "principle of maximum silent surprises" crap I'd use a scripting language). Until now I just assumed these were a compiler bugs, but if this "let's let the programmer *think* this is working the way they intended" behavior is intentional just for the sake of Stewart's (ii) and (iii), well then that's terrible and absolutely needs to change.
Apr 12 2009
Stewart Gordon Wrote:At the moment, the problem seems to be that the compiler is silently ignoring many cases of (a), (b) and (c) alike. Some people argue that the spec doesn't forbid such use of inapplicable attributes explicitly, and so the compiler's treatment of these cannot be called a bug. I argue that this isn't right. Nothing I've managed to find in the spec states or implies that such obviously wrong code is allowed. So, by applying common sense, one would conclude that it isn't allowed.Such mood was always in the spec: "AlignAttribute is ignored when applied to declarations that are not structs or struct members".
Apr 13 2009
Kagamin wrote:Stewart Gordon Wrote:I never saw that before. So it doesn't work for class members? And it won't change the alignment of unions if applied to union members (by changing the maximum alignment of the members)?At the moment, the problem seems to be that the compiler is silently ignoring many cases of (a), (b) and (c) alike. Some people argue that the spec doesn't forbid such use of inapplicable attributes explicitly, and so the compiler's treatment of these cannot be called a bug. I argue that this isn't right. Nothing I've managed to find in the spec states or implies that such obviously wrong code is allowed. So, by applying common sense, one would conclude that it isn't allowed.Such mood was always in the spec: "AlignAttribute is ignored when applied to declarations that are not structs or struct members".
Apr 13 2009
On Mon, Apr 13, 2009 at 2:05 PM, Frits van Bommel <fvbommel remwovexcapss.nl> wrote:Kagamin wrote:that theStewart Gordon Wrote:At the moment, the problem seems to be that the compiler is silently ignoring many cases of (a), (b) and (c) alike. =C2=A0Some people argue =sospec doesn't forbid such use of inapplicable attributes explicitly, and=e specthe compiler's treatment of these cannot be called a bug. I argue that this isn't right. =C2=A0Nothing I've managed to find in th=bystates or implies that such obviously wrong code is allowed. =C2=A0So, =dapplying common sense, one would conclude that it isn't allowed.Such mood was always in the spec: "AlignAttribute is ignored when applie='tto declarations that are not structs or struct members".I never saw that before. So it doesn't work for class members? And it won=change the alignment of unions if applied to union members (by changing t=hemaximum alignment of the members)?align is defined in terms of the companion C compiler. align(16) int foo; does not guarantee that foo.offsetof is aligned to 16 by= tes. Since C doesn't have D classes, the align attribute makes little sense here= .
Apr 13 2009
On Mon, 13 Apr 2009 16:44:25 +0400, Tomas Lindquist Olsen <tomas.l.olsen gmail.com> wrote:On Mon, Apr 13, 2009 at 2:05 PM, Frits van Bommel <fvbommel remwovexcapss.nl> wrote:You are kind of contradict yourself. Let's assme that align is defined in terms of the companion C compiler. Then, since C doesn't have D classes, the align attribute makes little sense when applied to /D classes/. I don't know how to judge about C built-in types from that.Kagamin wrote:align is defined in terms of the companion C compiler. align(16) int foo; does not guarantee that foo.offsetof is aligned to 16 bytes. Since C doesn't have D classes, the align attribute makes little sense here.Stewart Gordon Wrote:I never saw that before. So it doesn't work for class members? And it won't change the alignment of unions if applied to union members (by changing the maximum alignment of the members)?At the moment, the problem seems to be that the compiler is silently ignoring many cases of (a), (b) and (c) alike. Some people argue that the spec doesn't forbid such use of inapplicable attributes explicitly, and so the compiler's treatment of these cannot be called a bug. I argue that this isn't right. Nothing I've managed to find in the spec states or implies that such obviously wrong code is allowed. So, by applying common sense, one would conclude that it isn't allowed.Such mood was always in the spec: "AlignAttribute is ignored when applied to declarations that are not structs or struct members".
Apr 13 2009
On Mon, Apr 13, 2009 at 3:00 PM, Denis Koroskin <2korden gmail.com> wrote:On Mon, 13 Apr 2009 16:44:25 +0400, Tomas Lindquist Olsen <tomas.l.olsen gmail.com> wrote:e thatOn Mon, Apr 13, 2009 at 2:05 PM, Frits van Bommel <fvbommel remwovexcapss.nl> wrote:Kagamin wrote:Stewart Gordon Wrote:At the moment, the problem seems to be that the compiler is silently ignoring many cases of (a), (b) and (c) alike. =C2=A0Some people argu=ndthe spec doesn't forbid such use of inapplicable attributes explicitly, a=theso the compiler's treatment of these cannot be called a bug. I argue that this isn't right. =C2=A0Nothing I've managed to find in =, byspec states or implies that such obviously wrong code is allowed. =C2=A0So=nseYou are kind of contradict yourself. Let's assme that align is defined in terms of the companion C compiler. Then, since C doesn't have D classes, the align attribute makes little se=align is defined in terms of the companion C compiler. align(16) int foo; does not guarantee that foo.offsetof is aligned to 16 bytes. Since C doesn't have D classes, the align attribute makes little sense here.I never saw that before. So it doesn't work for class members? And it won't change the alignment of unions if applied to union members (by changing the maximum alignment of the members)?applying common sense, one would conclude that it isn't allowed.Such mood was always in the spec: "AlignAttribute is ignored when applied to declarations that are not structs or struct members".when applied to /D classes/. I don't know how to judge about C built-in types from that.Yes now I read it again I can see it doesn't make much sense. What I meant was just to say that align does not work for classes!!! What also snuck in there was that align(N) provides no guarantee that it will actually affect any field offsets. It wasn't supposed to have anything to do with the discussion, so just ignore it if you will...
Apr 13 2009
Frits van Bommel wrote:Kagamin wrote:<snip>http://www.digitalmars.com/d/1.0/class.html "The D compiler is free to rearrange the order of fields in a class to optimally pack them in an implementation-defined manner. Consider the fields much like the local variables in a function - the compiler assigns some to registers and shuffles others around all to get the optimal stack frame layout. This frees the code designer to organize the fields in a manner that makes the code more readable rather than being forced to organize it according to machine optimization rules. Explicit control of field layout is provided by struct/union types, not classes."Such mood was always in the spec: "AlignAttribute is ignored when applied to declarations that are not structs or struct members".I never saw that before. So it doesn't work for class members?And it won't change the alignment of unions if applied to union members (by changing the maximum alignment of the members)?I'm not sure what you mean.... But there seem to be a few issues with the behaviour of align. I'll have to investigate.... Stewart.
Apr 13 2009
Stewart Gordon wrote:Frits van Bommel wrote:Right, forgot about that bit. Probably because AFAIK no D compiler actually reorganizes them... (How does this combine with the "D ABI" anyway? I know binary compatibility between the different compilers is a bit of a pipe dream at the moment, but the only way that could work would be to standardize any and all shuffling of class fields...)Kagamin wrote:<snip>http://www.digitalmars.com/d/1.0/class.html "The D compiler is free to rearrange the order of fields in a class to optimally pack them in an implementation-defined manner. Consider the fields much like the local variables in a function - the compiler assigns some to registers and shuffles others around all to get the optimal stack frame layout. This frees the code designer to organize the fields in a manner that makes the code more readable rather than being forced to organize it according to machine optimization rules. Explicit control of field layout is provided by struct/union types, not classes."Such mood was always in the spec: "AlignAttribute is ignored when applied to declarations that are not structs or struct members".I never saw that before. So it doesn't work for class members?Unions are normally aligned to the maximum alignment for any member. Now consider: union U { align(1) void* p; ubyte[size_t.sizeof] bytes; } union U2 { align(4) ubyte[12] data; char[12] str; } What are U.alignof and U2.alignof? According to that piece of the spec, those align() attributes should be useless. However, according to DMD[1] U.alignof is 1, and without the attribute it's 4. U2 on the other hand is align(1) regardless of attribute. It seems DMD disagrees with the spec here. Same goes for GDC, except U.alignof is 8 without the attribute instead of 4 because I'm using a 64-bit version. LDC seems to agree with the spec (it ignores the aligns), but that may just be because it doesn't fully support align() in the first place... [1]: 1.042 on Linux: void main() { printf("%d %d\n", cast(int)U.alignof, cast(int)U2.alignof); }And it won't change the alignment of unions if applied to union members (by changing the maximum alignment of the members)?I'm not sure what you mean....
Apr 13 2009
Frits van Bommel wrote:Stewart Gordon wrote:<snip> [rearrangement of class fields]Right, forgot about that bit. Probably because AFAIK no D compiler actually reorganizes them... (How does this combine with the "D ABI" anyway? I know binary compatibility between the different compilers is a bit of a pipe dream at the moment, but the only way that could work would be to standardize any and all shuffling of class fields...)Good question. But AAs are another thing that's implementation defined at the moment. <snip>Unions are normally aligned to the maximum alignment for any member. Now consider: union U { align(1) void* p; ubyte[size_t.sizeof] bytes; } union U2 { align(4) ubyte[12] data; char[12] str; } What are U.alignof and U2.alignof? According to that piece of the spec, those align() attributes should be useless. However, according to DMD[1] U.alignof is 1, and without the attribute it's 4. U2 on the other hand is align(1) regardless of attribute.<snip> Sounds like a bug. Surely, align isn't applicable to unions at all. IINM the members of a union, by design, start at the same offset. An anonymous struct within a union, or an anonymous union within a struct, might have alignment - in either case, it would be in relation to the struct. Stewart.
Apr 13 2009
Stewart Gordon wrote:Definitely.Unions are normally aligned to the maximum alignment for any member. Now consider: union U { align(1) void* p; ubyte[size_t.sizeof] bytes; } union U2 { align(4) ubyte[12] data; char[12] str; } What are U.alignof and U2.alignof? According to that piece of the spec, those align() attributes should be useless. However, according to DMD[1] U.alignof is 1, and without the attribute it's 4. U2 on the other hand is align(1) regardless of attribute.<snip> Sounds like a bug.Surely, align isn't applicable to unions at all. IINM the members of a union, by design, start at the same offset.Not so, the alignment of each member should be respected. Most obviously, a union U consisting of a single member x should have U.alignof == x.alignof. An anonymous struct withina union, or an anonymous union within a struct, might have alignment - in either case, it would be in relation to the struct.Stewart.
Apr 14 2009
Don wrote:Stewart Gordon wrote:<snip>But the offset of a union member is always zero. So what would this do?Surely, align isn't applicable to unions at all. IINM the members of a union, by design, start at the same offset.Not so, the alignment of each member should be respected.Most obviously, a union U consisting of a single member x should have U.alignof == x.alignof.<snip> Yes, by propagating the union's alignment (relative to the containing struct) to the member. Stewart.
Apr 14 2009
Stewart Gordon wrote:Don wrote:It should make sure the union is aligned appropriately in a containing struct, meaning U.alignof >= M.alignof for all members M. Specifying per-member alignment allows you to change that member's effect on the union's alignment.Stewart Gordon wrote:<snip>But the offset of a union member is always zero. So what would this do?Surely, align isn't applicable to unions at all. IINM the members of a union, by design, start at the same offset.Not so, the alignment of each member should be respected.But the union's alignment needs to be sufficient for all members, so it depends on the maximum alignment of all members.Most obviously, a union U consisting of a single member x should have U.alignof == x.alignof.<snip> Yes, by propagating the union's alignment (relative to the containing struct) to the member.
Apr 14 2009
Frits van Bommel wrote:Stewart Gordon wrote:<snip>But alignment of a member within a structure and alignment of the whole structure relative to an outer one are two distinct concepts. What sense is there in being able to use one to control the other?But the offset of a union member is always zero. So what would this do?It should make sure the union is aligned appropriately in a containing struct, meaning U.alignof >= M.alignof for all members M. Specifying per-member alignment allows you to change that member's effect on the union's alignment.That's only because you want to be able to attach alignments to individual members of a union. And I still don't know why. If you want a union to have a certain alignment relative to a struct in which it's contained, in what cases is it not sufficient to put the align attribute on the union's instance in the struct? Stewart.But the union's alignment needs to be sufficient for all members, so it depends on the maximum alignment of all members.Most obviously, a union U consisting of a single member x should have U.alignof == x.alignof.<snip> Yes, by propagating the union's alignment (relative to the containing struct) to the member.
Apr 14 2009
Stewart Gordon wrote:Frits van Bommel wrote:I'm not sure why you think unions are so different to structs. They are identical in most respects -- including requirements for alignment of members.Stewart Gordon wrote:<snip>But alignment of a member within a structure and alignment of the whole structure relative to an outer one are two distinct concepts. What sense is there in being able to use one to control the other?But the offset of a union member is always zero. So what would this do?It should make sure the union is aligned appropriately in a containing struct, meaning U.alignof >= M.alignof for all members M. Specifying per-member alignment allows you to change that member's effect on the union's alignment.That's only because you want to be able to attach alignments to individual members of a union. And I still don't know why.But the union's alignment needs to be sufficient for all members, so it depends on the maximum alignment of all members.Most obviously, a union U consisting of a single member x should have U.alignof == x.alignof.<snip> Yes, by propagating the union's alignment (relative to the containing struct) to the member.If you want a union to have a certain alignment relative to a struct in which it's contained, in what cases is it not sufficient to put the align attribute on the union's instance in the struct?In cases where you don't know what the containing struct is. The union may just be a type returned from a template, for example.
Apr 14 2009
Don wrote:Stewart Gordon wrote:<snip>I still don't know what you mean.That's only because you want to be able to attach alignments to individual members of a union. And I still don't know why.I'm not sure why you think unions are so different to structs. They are identical in most respects -- including requirements for alignment of members.If you don't know what the containing struct is, you probably also don't know what member alignment that struct requires. The person who creates the struct, OTOH, does know. So why are you trying to do that person's job? Stewart.If you want a union to have a certain alignment relative to a struct in which it's contained, in what cases is it not sufficient to put the align attribute on the union's instance in the struct?In cases where you don't know what the containing struct is. The union may just be a type returned from a template, for example.
Apr 14 2009
Stewart Gordon wrote:Don wrote:You know ahead of time that you're going to use this union everywhere and that it should have proper alignment. If you still want to put the align attribute everywhere it's used instead, allow me to shoot you. Granted, you can replace your named union with a struct of the same name containing an anonymous union, and put the align attribute on that. That wouldn't be too odious (as long as the language specification mentioned the workaround), but since you already have align for unions, why bother changing it?Stewart Gordon wrote:<snip>I still don't know what you mean.That's only because you want to be able to attach alignments to individual members of a union. And I still don't know why.I'm not sure why you think unions are so different to structs. They are identical in most respects -- including requirements for alignment of members.If you don't know what the containing struct is, you probably also don't know what member alignment that struct requires. The person who creates the struct, OTOH, does know. So why are you trying to do that person's job? Stewart.If you want a union to have a certain alignment relative to a struct in which it's contained, in what cases is it not sufficient to put the align attribute on the union's instance in the struct?In cases where you don't know what the containing struct is. The union may just be a type returned from a template, for example.
Apr 14 2009
Stewart Gordon wrote:Don wrote:You're acting as if there's a big difference between unions and structs, and there isn't. Read the spec, the only differences are at construction, and struct literals.Stewart Gordon wrote:<snip>I still don't know what you mean.That's only because you want to be able to attach alignments to individual members of a union. And I still don't know why.I'm not sure why you think unions are so different to structs. They are identical in most respects -- including requirements for alignment of members.Yes you do. The union doesn't control the alignment of the surrounding struct. It only controls the alignment of itself inside that struct. The person who createsIf you don't know what the containing struct is, you probably also don't know what member alignment that struct requires.If you want a union to have a certain alignment relative to a struct in which it's contained, in what cases is it not sufficient to put the align attribute on the union's instance in the struct?In cases where you don't know what the containing struct is. The union may just be a type returned from a template, for example.the struct, OTOH, does know.They do NOT know. Not without probing every member in the union. So why are you trying to do that person'sjob?No, you know what alignment the member requires. By the way, there doesn't even need to be a surrounding struct! An instance of the union on the stack may itself need to be aligned. And you can even create a bare union on the heap.
Apr 15 2009
Don wrote:Stewart Gordon wrote:<snip>Don wrote:No, you have to add to that the differences inherited from C. Moreover, what difference could possibly be bigger than that between the basic essence of structs and the basic essence of unions? http://www.digitalmars.com/d/1.0/struct.html "They work like they do in C, with the following exceptions:" It's true that "alignment can be explicitly specified" is in there. But I'm not sure that Walter really meant it to apply to unions as well as structs. Especially given that it makes no comment (that I've found) on what align is meant to do in a union. Moreover, http://www.digitalmars.com/d/1.0/attribute.html#align "Specifies the alignment of struct members."You're acting as if there's a big difference between unions and structs, and there isn't. Read the spec, the only differences are at construction, and struct literals.I'm not sure why you think unions are so different to structs. They are identical in most respects -- including requirements for alignment of members.I still don't know what you mean.I thought that was meant to be controlled by an align applied to the union instance as a member of the struct, rather than by an align applied to the union itself. Only in the case of anonymous unions are they one and the same.Yes you do. The union doesn't control the alignment of the surrounding struct. It only controls the alignment of itself inside that struct.If you don't know what the containing struct is, you probably also don't know what member alignment that struct requires.If you want a union to have a certain alignment relative to a struct in which it's contained, in what cases is it not sufficient to put the align attribute on the union's instance in the struct?In cases where you don't know what the containing struct is. The union may just be a type returned from a template, for example.?? ISTM all they really need to know is the overall size of the union, which is equal to the size of the union's largest member (which is easy to find out).The person who creates the struct, OTOH, does know.They do NOT know. Not without probing every member in the union.So why are you trying to do that person's<snip> What are the cases in which a member _requires_ a certain alignment? OK, so there's one case: pointers in order to make sure the GC works properly. But this is absolute alignment. Maybe it's just me, but given that talk of alignment is nearly always in relation to structs, I'd made it out to be talking about relative alignment. Maybe the spec just needs to be clearer.... Stewart.job?No, you know what alignment the member requires.
Apr 15 2009
Stewart Gordon wrote:Don wrote:In the compiler, struct and union share almost all of their code. Basically, a union is just a struct where all the elements are on top of each other. Which is a tiny difference compared (say) to the difference between structs and classes. For example, this works: union foo(T) { public: static int bar(int x) { return x*2; } } void main() { assert (foo!(int).bar(7)==14); }Stewart Gordon wrote:<snip>Don wrote:No, you have to add to that the differences inherited from C. Moreover, what difference could possibly be bigger than that between the basic essence of structs and the basic essence of unions?You're acting as if there's a big difference between unions and structs, and there isn't. Read the spec, the only differences are at construction, and struct literals.I'm not sure why you think unions are so different to structs. They are identical in most respects -- including requirements for alignment of members.I still don't know what you mean.http://www.digitalmars.com/d/1.0/struct.html "They work like they do in C, with the following exceptions:" It's true that "alignment can be explicitly specified" is in there. But I'm not sure that Walter really meant it to apply to unions as well as structs. Especially given that it makes no comment (that I've found) on what align is meant to do in a union.In a struct, align(4) int X; means, pad with zero bytes until the address you're up to is a multiple of 4, then put the int at that address. The address for the next element is the first byte past the int. In a union, align(4) int X; means, pad with zero bytes until the address you're up to is a multiple of 4, then put the int at that address. The address for the next element is the first byte of the union. Moreover,http://www.digitalmars.com/d/1.0/attribute.html#align "Specifies the alignment of struct members."Static arrays, eg float[4]. Must be aligned if you want to use the movaps instruction (which is 4X faster than the unaligned instruction). Alignment requirements are rare, even for structs.I thought that was meant to be controlled by an align applied to the union instance as a member of the struct, rather than by an align applied to the union itself. Only in the case of anonymous unions are they one and the same.Yes you do. The union doesn't control the alignment of the surrounding struct. It only controls the alignment of itself inside that struct.If you don't know what the containing struct is, you probably also don't know what member alignment that struct requires.If you want a union to have a certain alignment relative to a struct in which it's contained, in what cases is it not sufficient to put the align attribute on the union's instance in the struct?In cases where you don't know what the containing struct is. The union may just be a type returned from a template, for example.?? ISTM all they really need to know is the overall size of the union, which is equal to the size of the union's largest member (which is easy to find out).The person who creates the struct, OTOH, does know.They do NOT know. Not without probing every member in the union.So why are you trying to do that person's<snip> What are the cases in which a member _requires_ a certain alignment?job?No, you know what alignment the member requires.OK, so there's one case: pointers in order to make sure the GC works properly. But this is absolute alignment. Maybe it's just me, but given that talk of alignment is nearly always in relation to structs, I'd made it out to be talking about relative alignment. Maybe the spec just needs to be clearer.... Stewart.Probably. Unions tend to get forgotten.
Apr 16 2009
On Thu, Apr 16, 2009 at 12:34 PM, Don <nospam nospam.com> wrote:Stewart Gordon wrote:reDon wrote:Stewart Gordon wrote:<snip>Don wrote:I'm not sure why you think unions are so different to structs. They a=,You're acting as if there's a big difference between unions and structs=identical in most respects -- including requirements for alignment of members.I still don't know what you mean.n,and there isn't. Read the spec, the only differences are at constructio=over,and struct literals.No, you have to add to that the differences inherited from C. =C2=A0More==A0Butwhat difference could possibly be bigger than that between the basic essence of structs and the basic essence of unions?In the compiler, struct and union share almost all of their code. Basically, a union is just a struct where all the elements are on top of each other. Which is a tiny difference compared (say) to the difference between structs and classes. For example, this works: union foo(T) { public: =C2=A0 static int bar(int x) { return x*2; } } void main() { =C2=A0assert (foo!(int).bar(7)=3D=3D14); }http://www.digitalmars.com/d/1.0/struct.html "They work like they do in C, with the following exceptions:" It's true that "alignment can be explicitly specified" is in there. =C2=d) onI'm not sure that Walter really meant it to apply to unions as well as structs. =C2=A0Especially given that it makes no comment (that I've foun=Thewhat align is meant to do in a union.In a struct, align(4) int X; means, pad with zero bytes until the address you're up to is a multiple of 4, then put the int at that address. The address for the next element is the first byte past the int. In a union, align(4) int X; means, pad with zero bytes until the address you're up to is a multiple of 4, then put the int at that address. =C2=A0=address for the next element is the first byte of the union. =C2=A0Moreover,he alignhttp://www.digitalmars.com/d/1.0/attribute.html#align "Specifies the alignment of struct members."If you want a union to have a certain alignment relative to a struct in which it's contained, in what cases is it not sufficient to put t=nattribute on the union's instance in the struct?In cases where you don't know what the containing struct is. The unio='tmay just be a type returned from a template, for example.If you don't know what the containing struct is, you probably also don=onI thought that was meant to be controlled by an align applied to the uni=know what member alignment that struct requires.Yes you do. The union doesn't control the alignment of the surrounding struct. It only controls the alignment of itself inside that struct.heinstance as a member of the struct, rather than by an align applied to t=d theunion itself. =C2=A0Only in the case of anonymous unions are they one an=tosame.?? ISTM all they really need to know is the overall size of the union, which is equal to the size of the union's largest member (which is easy =The person who creates the struct, OTOH, does know.They do NOT know. Not without probing every member in the union.So now we just need align(N) for the storage as well as field offsets, to actually make that useful.find out).Static arrays, eg float[4]. Must be aligned if you want to use the movaps instruction (which is 4X faster than the unaligned instruction).So why are you trying to do that person's<snip> What are the cases in which a member _requires_ a certain alignment?job?No, you know what alignment the member requires.Alignment requirements are rare, even for structs., but givenOK, so there's one case: pointers in order to make sure the GC works properly. =C2=A0But this is absolute alignment. =C2=A0Maybe it's just me=itthat talk of alignment is nearly always in relation to structs, I'd made=eds to beout to be talking about relative alignment. =C2=A0Maybe the spec just ne=clearer.... Stewart.Probably. Unions tend to get forgotten.
Apr 16 2009
Frits van Bommel wrote:Stewart Gordon wrote:Or the least common multiple, assuming that align accepts arguments that are not powers of 2.Don wrote:It should make sure the union is aligned appropriately in a containing struct, meaning U.alignof >= M.alignof for all members M. Specifying per-member alignment allows you to change that member's effect on the union's alignment.Stewart Gordon wrote:<snip>But the offset of a union member is always zero. So what would this do?Surely, align isn't applicable to unions at all. IINM the members of a union, by design, start at the same offset.Not so, the alignment of each member should be respected.But the union's alignment needs to be sufficient for all members, so it depends on the maximum alignment of all members.Most obviously, a union U consisting of a single member x should have U.alignof == x.alignof.<snip> Yes, by propagating the union's alignment (relative to the containing struct) to the member.
Apr 14 2009
Christopher Wright wrote:Frits van Bommel wrote:I have never seen "alignment" used to describe addresses at a multiple of anything but a power of two. In fact, common object file formats (That I know of: ELF and LLVM bitcode) enforce this by only allowing alignments to be specified as powers of two. ELF does this by storing the log of the alignment instead of the alignment itself; LLVM currently encodes the full value for backward compatibility but asserts if this isn't a power of two (or zero) and IIRC they plan to switch to log-storage for LLVM 3.0 if and when it comes out.But the union's alignment needs to be sufficient for all members, so it depends on the maximum alignment of all members.Or the least common multiple, assuming that align accepts arguments that are not powers of 2.
Apr 14 2009
On 2009-04-13 09:43:53 -0400, Frits van Bommel <fvbommel REMwOVExCAPSs.nl> said:(How does this combine with the "D ABI" anyway? I know binary compatibility between the different compilers is a bit of a pipe dream at the moment, but the only way that could work would be to standardize any and all shuffling of class fields...)Interesting observation. But you don't necessarily need to standardize the shuffling algorithm. If the offsets for fields in a class could be resolved at link time (the compiler could dump the offsets in the object file), then the linker could arange the final executable for any layout. The same could be done for virtual functions too, giving us a true non-fragile ABI capable of supporting changes in the order of member fields and functions. -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 14 2009
Michel Fortin wrote:On 2009-04-13 09:43:53 -0400, Frits van Bommel <fvbommel REMwOVExCAPSs.nl> said:Some problems I see with this: * Good luck implementing that for all of OMF (DMD/win), COFF (GDC/win), ELF(anything *nix). * Same for LLVM bitcode, for LDC and any other future compilers based on LLVM. Especially because this is a *typed* IR, and optimizations usually work best if you don't work around types with pointer<-->int conversions. * Implementing this without reducing the quality of generated code; some architectures allow better instructions if you know the offset is below a certain limit, which must then be known at compile-time (except for something like LLVM, where link-time is early enough for this if you're generating IR instead of native code at first). * If you do this, you don't know how big a class body is at compile-time (because padding is unknown). So the compiler doesn't know what size to allocate in the stack frame for 'scope c = new C;" So yeah, in theory this might be possible, but I don't know of any object format that supports all these without it pessimizing the generated code. I just don't think it's worth it at the moment. Though if you feel like extending LLVM to support this... (it's IR object format is probably closest to efficiently supporting something like this due to arbitrarily-complex constant expression support in IR and inter-module optimizations. You might be able to get it to work, as long as the offsets and sizes are known by the time the assembler gets involved) It would certainly allow support for some other cool stuff, like adding fields and (virtual) methods to classes from other object files (aka modules).(How does this combine with the "D ABI" anyway? I know binary compatibility between the different compilers is a bit of a pipe dream at the moment, but the only way that could work would be to standardize any and all shuffling of class fields...)Interesting observation. But you don't necessarily need to standardize the shuffling algorithm. If the offsets for fields in a class could be resolved at link time (the compiler could dump the offsets in the object file), then the linker could arange the final executable for any layout. The same could be done for virtual functions too, giving us a true non-fragile ABI capable of supporting changes in the order of member fields and functions.
Apr 14 2009