!standard 4.9(2-13) 14-05-09 AC95-00260/00 !class Amendment 13-05-09 !status received no action 14-05-09 !status received 14-04-16 !subject Why isn't 'Size static? !summary !appendix !topic Why isn't 'Size static? !reference RM12 4.9(2-13) !from Adam Beneschan 14-04-16 !discussion Is there any reason why T'Size shouldn't be a static expression, if T is a definite type? I'm running into problems trying to do something like type T_As_Bits is mod 2**T'Size; where T is either a definite private type, or an access type. The rules in 4.9(2-13) don't appear to allow this, but I don't see a good reason why. There may be other representation-related attributes which logically should be static also (like 'Position, 'First_Bit, 'Stream_Size on an access type). *************************************************************** From: Randy Brukardt Sent: Thursday, April 17, 2014 12:08 AM > Is there any reason why T'Size shouldn't be a static expression, if T > is a definite type? Of course. Defining exactly what cases allow it to be static would be rather complicated. "Definite" surely isn't enough, since a subtype with a dynamic constraint is still definite. Given that implementations can use non-contiguous representations for composite types, we'd probably want to exclude some additional kinds of subtypes (perhaps all types with discriminant-dependent components?). And of course, any component that has a non-static 'Size (by whatever definition we came up with) should prevent the enclosing composite object from having a static size (how could one add two non-static sizes and end up with something static?). That's probably more complication than any of the language design teams wanted to wrestle with. Luckily, you didn't ask if there was a *good* reason! :-) > I'm running into > problems trying to do something like > > type T_As_Bits is mod 2**T'Size; > > where T is either a definite private type, or an access type. > The rules in 4.9(2-13) don't appear to allow this, but I don't see a > good reason why. Oh, now you went and did ask about a good reason. Can't help you there. :-) I've run into this as well, but a quick look at the complications involved (it would pretty much require new line items in 4.9 for each specific attribute we wanted to allow) dampened my enthusiasm. As far as the actual problem goes, usually it turns out that T has a Size clause of some kind (or should have one for portability). In that case, I take the expression of the Size clause and make a constant out of it. Then I can use that in both places (the Size aspect and in the later type declaration). Sometimes I've had to do that recursively (if T'Size uses C'Size). The result is usually just as readable and no more likely to get broken by future maintenance, so given that the workaround isn't usually much worse than the original code, it's hard to get excited about the nasty work of defining T'Size as static in some proper way (other than the scalar and string cases, which already can be static). For example: type T ... with Size => ; type T_as_Bits is mod 2**T'Size; becomes: Size_of_T : constant := ; type T ... with Size => Size_of_T; type T_as_Bits is mod 2**Size_of_T; > There may be other representation-related attributes which logically > should be static also (like 'Position, 'First_Bit, 'Stream_Size on an > access type). Probably, but as each would have to be a case-by-case basis (you forgot 'Alignment, BTW), it seems that the unpleasantness would multiply. I suppose if enough people make noise, we might get more ambitious. The squeaky wheel gets the grease, after all. :-) *************************************************************** From: Bob Duff Sent: Thursday, April 17, 2014 10:42 AM > Luckily, you didn't ask if there was a *good* reason! :-) I agree with your reasons, and I think they're good ones. In addition: Allowing it for private types would break privacy. Clearly T'Size can't be static (for clients): package P is type T is private; private type T is array (1..Read_From_Keyboard) of ...; end P; Unlike many ARG members, I am not 100% opposed to breaking privacy. But I'm at least 99% opposed. Also, many compilers do record layout and the like in the back end. But static values need to be known to the front end. So allowing it would be an earthquake for those compilers. As Randy showed, it's a minor inconvenience to programmers, which is not worth any earthquakes. > work of defining T'Size as static in some proper way (other than the > scalar and string cases, which already can be static). String_Subtype'Size is never static. *************************************************************** From: Adam Beneschan Sent: Thursday, April 17, 2014 11:10 AM > > Luckily, you didn't ask if there was a *good* reason! :-) > > I agree with your reasons, and I think they're good ones. > > In addition: > > Allowing it for private types would break privacy. > Clearly T'Size can't be static (for clients): > > package P is > type T is private; > private > type T is array (1..Read_From_Keyboard) of ...; > end P; For some reason I didn't think of this case. It does pretty much make the whole idea impossible. Unless we were to add a new aspect that would prevent the completion from being an unknown size: package P is type T is private with Definite_Size; private -- the aspect would make this illegal type T is array (1..Read_From_Keyboard) of ...; end P; So it's possible in theory to provide for a feature like this, but it would be a lot of work, and the problem case I ran into was quite specialized and something I'd expect others to run into very rarely. So I'm sure it wouldn't be worthwhile. Anyway, I was able to work around my particular problem. *************************************************************** From: Jeffrey Carter Sent: Thursday, April 17, 2014 1:29 PM To the non-language-lawyer user, it seems reasonable for 'Size to be static for Scalar types Access types Constrained array types with static index constraints and a component type having static 'Size Non-discriminated record types with all components having static 'Size > Also, many compilers do record layout and the like in the back end. > But static values need to be known to the front end. > So allowing it would be an earthquake for those compilers. In light of this, maybe record types are not so reasonable after all. *************************************************************** From: Tucker Taft Sent: Thursday, April 17, 2014 4:44 PM > To the non-language-lawyer user, it seems reasonable for 'Size to be > static for > > Scalar types > Access types > Constrained array types with static index constraints and a component > type having static 'Size I would probably agree with these, and also perhaps make a special case for System.Address ;-) to avoid the kludge of having to use System.Storage_Elements.Integer_Address'Size. One issue with arrays is packed vs. unpacked. Packing might also be a backend thing for some compilers. Given that, it might be better to just stick with scalars and access types. You can always specify 'Component_Size if you want on an array, and then do the multiplication yourself with some confidence. > Non-discriminated record types with all components having static 'Size For the reason stated below, record types are probably not feasible. >> Also, many compilers do record layout and the like in the back end. >> But static values need to be known to the front end. >> So allowing it would be an earthquake for those compilers. > > In light of this, maybe record types are not so reasonable after all. ***************************************************************