!standard B.3(71.3/3) 16-10-02 AI12-0184-1/03 !class Amendment 16-03-23 !status Amendment 1-2012 16-08-01 !status ARG Approved 11-0-1 16-06-12 !status work item 16-03-23 !status received 15-04-24 !priority Low Low !difficulty Easy Easy !subject Long Long C Data Types !summary Implementation Advice is added that Ada types that correspond to the C99 64-bit types be defined when possible. !problem The C99 standard defines some additional standard types: long long long long int signed long long signed long long int Long long signed integer type. Capable of containing at least the [-9223372036854775807, +9223372036854775807] range; thus, it is at least 64 bits in size. unsigned long long unsigned long long int Similar to long long, but unsigned. Specified since the C99 version of the standard. !proposal (See Wording.) !wording Add after B.3(71.3/3): An implementation should provide unsigned_long_long and long_long as 64-bit modular and signed integer types (respectively) in package Interfaces.C if the C implementation supports unsigned long long and long long as 64-bit types. !discussion We already have Wide_Wide_ types, so there can't be any problem with Long_Long_ types. It would be cool if we had a type that was both: Wide_Wide_Long_Long_Int. ;-) Seriously, we have to be careful here. If we just dumped these types into Interfaces.C, we're implicitly requiring all Ada compilers to support 64-bit types. That's inappropriate on embedded hardware without 64-bit support (especially so on 8-bit and 16-bit targets - even though Ada is not much used on such targets it would be silly to prevent it). B.3(62) already allows adding any types that the implementation needs to ease interfacing with the C implementation. So, we just add Implementation Advice that the appropriate types be supported if appropriate. That requires nothing on an implementation (IA can always be ignored, if documented). !corrigendum B.3(71.2/3) @dinsa @xbullet also apply to the return object of a function.> @dinst An implementation should provide unsigned_long_long and long_long as 64-bit modular and signed integer types (respectively) in package Interfaces.C if the C implementation supports unsigned long long and long long as 64-bit types. !ASIS No ASIS effect. !ACATS test An ACATS C-Test is needed to check that the new capabilities are supported. !appendix !topic some missing long long C data types !reference Ada 2012 RM B.3 Interfacing with C and C++ !from Pascal Pignard 15-12-21 !keywords C type !discussion From https://en.wikipedia.org/wiki/C_data_types: long long long long int signed long long signed long long int Long long signed integer type. Capable of containing at least the [-9223372036854775807, +9223372036854775807] range; thus, it is at least 64 bits in size. Specified since the C99 version of the standard. unsigned long long unsigned long long int Similar to long long, but unsigned. Specified since the C99 version of the standard. These new types coming with C99 are missing in the library package Interfaces.C (annex B3). **************************************************************** !topic some missing long long C data types !reference Ada 2012 RM B.3 Interfacing with C and C++ !from Pascal Pignard 15-12-21 !keywords C type !discussion Note: I've never seen any reply on the list since I sent the message end of last year, sorry if this has been already taken in account. From https://en.wikipedia.org/wiki/C_data_types: long long long long int signed long long signed long long int Long long signed integer type. Capable of containing at least the [-9223372036854775807, +9223372036854775807] range; thus, it is at least 64 bits in size. Specified since the C99 version of the standard. unsigned long long unsigned long long int Similar to long long, but unsigned. Specified since the C99 version of the standard. These new types coming with C99 are missing in the library package Interfaces.C (annex B3). **************************************************************** From: Randy Brukardt Sent: Wednesday, March 30, 2016 6:52 PM > !topic some missing long long C data types > > Note: I've never seen any reply on the list since I sent the message > end of last year, sorry if this has been already taken in account. No answer was necessary: the types are clearly not in Interfaces.C, and so far as I'm aware we've never previously considered them, so we just opened an AI so the topic gets discussion. One question that has to be answered is how to avoid requiring 64-bit integers on targets for which that is not appropriate (surely 8-bit targets and probably 16-bit targets as well). Just sticking the types into Interfaces.C would certainly have that effect. It's not clear how C addresses this (it would seem even more important there, as C is used on more 8-bit and 16-bit targets than Ada is). Since the core of Ada only requires 16-bit integers, it would seem like madness to require much more just in one side issue (but one that is essentially required in a practical Ada compiler). This is especially concerning to me, since the shared generic model of Janus/Ada means that all operations inside of a generic unit for a formal integer or discrete type have to use the largest supported integer type. Forcing 64-bit support on a small target would have a devastating performance impact on generic instantiations (like Ada.Text_IO.Integer_IO). (I remember that supporting 16-bit integers on the Z80 was a chore - it's hard to imagine what a 64-bit integer would be like.) That has to be discussed. **************************************************************** From: Randy Brukardt Sent: Wednesday, March 30, 2016 7:14 PM ... > No answer was necessary: the types are clearly not in Interfaces.C, > and so far as I'm aware we've never previously considered them, so we > just opened an AI so the topic gets discussion. I forgot to mention the number in case you want to follow its progress: it is AI12-0184-1. (I haven't posted it yet, it will be in the next batch, posted sometime between now and the week of our Pisa meeting - early June.) **************************************************************** From: Brad Moore Sent: Wednesday, March 30, 2016 3:28 PM >!topic some missing long long C data types Personally, I would agree on the need for these. I recently ran into a case where I needed two routines that perform the same function, except one which used a subtype of Integer, and the other where I would have used a subtype of Long_Long_Integer, but could not so so in a portable manner so I ended up having to create my own type, which introduced the need for explicit conversions in many places in my code which is annoying. **************************************************************** From: Randy Brukardt Sent: Wednesday, March 30, 2016 7:11 PM ??? I don't see what requiring support in Intefaces.C for some predefined C types has to do with any Ada types in Standard. Using them for other than for interfacing is bad practice, and package Interfaces.C is optional anyway (so depending on it is never 100% portable). If you really care about portability you have to stick to Ada 2005 at the absolute most (there's only one Ada 2012 compiler) so anything done now is irrelevant for that purpose. I can't imagine requiring 64-bit support on all possible targets; that's essentially the same as locking the language only to 32-bit and 64-bit targets (and it would have negative effects even on 32-bit targets -- for Janus/Ada, a 64-bit integer is a non-standard Integer type specifically to avoid those negative effects). Integer and Long_Long_Integer are different types, so the routines would be different in any case. Converting between them would always need type conversions. Long_Long_Integer is not portable (it's not required, and in fact it is supposed to be rejected by Restriction No_Implementation_Identifiers). Good code never uses any of the types in Standard. (Sure, we all write sloppy code from time-to-time, but why should the Standard encourage that?) The only way to write portable Ada code that needs values >32767 is to declare your own types -- that's always been true and I doubt very much that we're going to change it just to make it easier for sloppy programs. One thing that has been missing from Ada is the ability to declare Ada discrete types with a C convention; the Standard requires one to derive them from some type in Interfaces.C but it's not at all clear to me why that's a good idea. All compilers that I am aware of treat all discrete types as C-compatible anyway, so it's really only a problem for pedants, but it does prevent maximizing the portability of one's code. (OTOH, we discussed this in passing when we were dealing with the enumeration type problem and decided for some reason that I don't recall not to fix it.) I think I better stop! (I'm probably off on the wrong tangent for whatever reason.) **************************************************************** From: Tucker Taft Sent: Wednesday, March 30, 2016 8:05 PM > I don't see what requiring support in Intefaces.C for some predefined > C types has to do with any Ada types in Standard. Using them for other > than interfaces is bad practice, and package Interfaces.C is optional > anyway (so depending on it is never 100% portable). I have a somewhat different view. I think that we ought to encourage implementors to include in Interfaces.C all of the types supported by the local "standard" C compiler. Since "long long XXX" is now a standard part of C, we should encourage implementors to include it in Interfaces.C. I am guessing most of them do already. It is true that it won't be 100% portable, but it should be portable to all environments where there is support for a C compiler that supports long long (which most of them do these days). Note that implementors are permitted to add declarations to Interfaces.C, and I suspect many of them attempt to match whatever is provided by the supported C compiler. **************************************************************** From: Randy Brukardt Sent: Wednesday, March 30, 2016 9:19 PM ??? I agree with all that you said above, but I don't see what it has to do with what I said or what Brad said (or, for that matter, with what the Ada Standard says). (Or why you think that your view is different than mine!) I said (or meant, anyway) that *in non-interfacing code*, you shouldn't be using declarations in Interfaces.C, or for that matter, declarations in Standard. Best practice in Ada is always to declare your own integer types. That's such a basic Ada tenet that I'd be surprised to hear anyone disagree with it (of course in sloppy, throwaway code, one ignores lots of best practices, but no one is likely to care about portability of that). And if you're only worried about 99% portability, then declaring your own types will work even for interfacing code (since all compilers I know of allow pretty much any discrete type to be C-compatible - you don't need a convention declaration, which is good since the language doesn't allow it anyway). You'd use the types in Interfaces.C only if you have an API that uses one of those predefined types. The question I have is about the cost of *requiring* long_long_int in Interfaces.C, as that appears to force 64-bit math regardless of the target. I'm surely not against *allowing* or even *encouraging* (i.e. Implementation Advice) long_long_int in Interfaces.C. Jeff reported privately that he couldn't find anything in the C 2011 Standard that made long_long_int optional, but of course that would mean that 8-bit C implementations would have to support 64-bit math (or ignore C 2011) -- and that seems to violate the Dewar rule (does the Dewar rule apply to the C Standard?? :-). But regardless of what the C Standard does or does not do, we need to consider whether we want to let the C people force such a requirement on us. I guess I do disagree with you on one point: for the vast majority of Ada compilers that do not share code generators with the C implementation, the cost of supporting long_long_int or any other C data type could be significant. (In general, Janus/Ada tries to map types it implements, and doesn't try to map types that it has no counterpart for.) That's especially true for smaller targets -- even if the C compiler has 64-bit types, that doesn't mean that it is somehow easy to support it in another code generator. (It's a huge amount of work to add a new discrete representation to Janus/Ada - it was designed with exactly 3 such representations for integers [8, 16, and 32 using those up] - I started adding a fourth signed representation for decimal types decades ago, but never finished it and there is no hint of an unsigned representation. I'd think similar things would be true for other code generators - if they don't already have 64-bit support, it would be very expensive to add it.) Thus I don't think whether or not the C compiler has long_long_int makes any difference -- the question is whether the Ada compiler supports them. If it does, then it certainly should support long_long_int. And if it doesn't, it isn't going to be able to magically support long_long_int whether or not the C compiler does. So I see this as an issue that potentially could prevent some existing compilers from ever being upgraded to Ada 202x. I'd think we'd want as few as possible barriers to implementers doing that, lest GNAT be the only "current" Ada compiler forever. P.S. As I mentioned before, forcing 64-bit support also would impact the performance on any non-64-bit target. Exactly how bad that would be is not clear to me (it's certainly not in the "sky-is-falling" category), but one has to evaluate any runtime universal expression in the largest integer type, and 64-bit operations (especially multiply and divide) are pretty expensive on smaller targets. **************************************************************** From: Tucker Taft Sent: Wednesday, March 30, 2016 9:33 PM I don't see requiring it, since as you point out, supporting Interfaces.C is optional to begin with. But we could strongly encourage it for implementations that already support 64-bit integers, and even specify the recommended names to use. And yes I agree it is almost always better to declare your own integer types, but sometimes the interfacing-to-the-outside-world requirements trump that, and you have an incentive to use the "external" types inside your program as well, at least in certain places. **************************************************************** From: Brad Moore Sent: Thursday, March 31, 2016 12:02 AM > I don't see what requiring support in Intefaces.C for some predefined > C types has to do with any Ada types in Standard. Using them for other > than interfaces is bad practice, and package Interfaces.C is optional > anyway (so depending on it is never 100% portable). Right, my response was more about the broader topic of providing support for 64 bit integers, than just within Interfaces.C. The example I brought up was more specifically about Long_Long_Integer. > If you really care about portability you have to stick to Ada 2005 at > the absolute most (there's only one Ada 2012 compiler) so anything > done now is irrelevant for that purpose. In my case, my approach is to provide compatibility using (at least) 3 different versions of the source. One for Ada 95, one for Ada 2005, and one for Ada 2012. I try to make use of the current language features applicable to each version of the standard. So there should be a flavour that fits most existing compilers today hopefully. That's about as portable as one can get, I would think. As more Ada 2012 compilers come available, more can move to the 2012 source baseline. > I can't imagine requiring 64-bit support on all possible targets; > that's essentially the same as locking the language only to 32-bit and > 64-bit targets (and it would have negative effects even on 32-bit > targets -- for Janus/Ada, a 64-bit integer is a non-standard Integer > type specifically to avoid those negative effects). > > Integer and Long_Long_Integer are different types, so the routines > would be different in any case. Converting between them would always > need type conversions. > > Long_Long_Integer is not portable (it's not required, and in fact it > is supposed to be rejected by Restriction No_Implementation_Identifiers). Maybe Long_Long_Integer wouldn't need to be required to be minimum 64 bits, but rather at least as long as Long_Integer, similar to how Long_Integer doesn't need to be more bits than Integer. There may be good reasons why that isn't workable, but it strikes me as maybe being a better option than leaving it to be implementation defined. > Good code never uses any of the types in Standard. (Sure, we all write > sloppy code from time-to-time, but why should the Standard encourage > that?) The only way to write portable Ada code that needs values > >32767 is to declare your own types -- that's always been true and I > doubt very much that we're going to change it just to make it easier for > sloppy programs. I don't consider my situation to be sloppy code, but beauty is in the eye of the beholder, as they say. In my case, my goal is to provide some library calls, without using generics, where the library calls are to be potentially retrofitted into existing code in some cases. The intent is to have it so the library calls as much as possible, can be inserted with a minimum amount of change to the existing code. For example, consider library calls for parallel loops, where an iterator type is needed for the loops. Some loops are OK with 32 bit iterator types, but others need 64 bit iterator types. Ideally, the iterator type used by the library should as best as possible match the iterator types used by the existing code, because it is the users iterator type that the library is trying to replace. If users use either the standard integer types directly, or hopefully at least use subtypes of those types rather than derived types or new types, then an iterator subtype provided by the library will match all of those cases, and not require explicit conversions. For derived types or new integer types, type conversions are needed, but at least the client of the library has the choice of deciding to use either approach. If one has the loop... declare subtype My_Integer is Integer; Sum : My_Integer := 0; begin for I in 1 .. 10 loop Sum := Sum + I; end loop; end; This compiles of course. But, if the declaration for My_Integer is changed to; type My_Integer is new Integer, then the code no longer compiles, as explicit conversions are needed to add I to Sum. Such loops are quite common, where the type of the Iterator really is one of the standard types. That may be one of the big reasons why people use subtypes, rather than new types in a lot of cases, because it fits better with the iterator types that are being used. I am not using Long_Integer, or Long_Long_Integer directly in my code, but rather something like; subtype Loop_Iteration_Index_Type is Long_Integer; By using a subtype, my code provides more flexibility in allowing clients to decide whether they want to use explicit casting or not. If I used a new type, then I am forcing more explicit conversions which some clients might find annoying. **************************************************************** From: Randy Brukardt Sent: Thursday, March 31, 2016 1:38 AM > Right, my response was more about the broader topic of providing > support for 64 bit integers, than just within Interfaces.C. > The example I brought up was more specifically about > Long_Long_Integer. Please don't confuse topics. They're only vaguely related. ... > As more Ada 2012 compilers come available, more can move to the 2012 > source baseline. Sure, but this is Ada 202x at the earliest. That's a *new* flavor of Ada beyond the ones we already have. Even if you have some new portability there, it sure as heck won't change what is available in any of the older versions. ... > > Long_Long_Integer is not portable (it's not required, and in fact it > > is supposed to be rejected by Restriction No_Implementation_Identifiers). > > Maybe Long_Long_Integer wouldn't need to be required to be minimum 64 > bits, but rather at least as long as Long_Integer, similar to how > Long_Integer doesn't need to be more bits than Integer. There may be > good reasons why that isn't workable, but it strikes me as maybe being > a better option than leaving it to be implementation defined. Names like Long_Long_Integer and Wide_Wide_Character are abominations that should not in the Standard the first place. They're obtrusive, emphasize the wrong thing, and scale badly (even while it appears obvious -- is it really easy to tell between Long_Long_Integer and Long_Long_Long_Integer?? 128-bit types seem inevitable.) I'm against any expansion of the use of names like these. The decision to make types other than Integer and Long_Integer "implementation-defined" was quite intentional. (And not my idea, I point out.) We didn't want people using those other types if they wanted any sort of portability (and preferably not at all). > > Good code never uses any of the types in Standard. (Sure, we all > > write sloppy code from time-to-time, but why should the Standard > > encourage > > that?) The only way to write portable Ada code that needs values > > >32767 is to declare your own types -- that's always been true and I > > doubt very much that we're going to change it just to make it easier > > for sloppy programs. > > I don't consider my situation to be sloppy code, but beauty is in the > eye of the beholder, as they say. > > In my case, my goal is to provide some library calls, without using > generics, where the library calls are to be potentially retrofitted > into existing code in some cases. The intent is to have it so the > library calls as much as possible, can be inserted with a minimum > amount of change to the existing code. This problem seems to be the exact reason that generics were invented. Any Ada user would expect to instantiate a generic (just like you need to do that to get I/O, or a container, or pretty much anything else useful). Unless you are trying to code for Janus/Ada, generics don't even have any significant runtime cost, so it's hard for me to see a good reason to avoid them. (And for Janus/Ada, you can get much smaller code by using a common generic that is instantiated a bunch of times.) > For example, consider library calls for parallel loops, where an > iterator type is needed for the loops. > > Some loops are OK with 32 bit iterator types, but others need > 64 bit iterator types. > > Ideally, the iterator type used by the library should as best as > possible match the iterator types used by the existing code, because > it is the users iterator type that the library is trying to replace. > If users use either the standard integer types directly, or hopefully > at least use subtypes of those types rather than derived types or new > types, then an iterator subtype provided by the library will match all > of those cases, and not require explicit conversions. For derived > types or new integer types, type conversions are needed, but at least > the client of the library has the choice of deciding to use either > approach. > > If one has the loop... > > declare > subtype My_Integer is Integer; > Sum : My_Integer := 0; > begin > for I in 1 .. 10 loop > Sum := Sum + I; > end loop; > end; > > This compiles of course. > > But, if the declaration for My_Integer is changed to; > type My_Integer is new Integer, then the code no longer compiles, > as explicit conversions are needed to add I to Sum. This is a red herring: (1) If you change subtype My_Integer to "is Long_Integer", the loop doesn't compile anymore, either. The type-free iterator is a special case for type Integer only. I can see your library for the special case of type Integer (only); otherwise it pretty much has to be generic. (2) If you had written the loop with a correct subtype in the first place: for I in My_Integer range 1 .. 10 loop then it doesn't matter how you change the declaration of My_Integer: subtype My_Integer is Integer; subtype My_Integer is Long_Integer; type My_Integer is range 0 .. 1000; all work fine. Since the original code was sloppy and mixed subtypes, it doesn't (necessarily) continue to work when the subtype is changed. > Such loops are quite common, where the type of the Iterator really is > one of the standard types. No, loops that are of type Integer are very common. Any other type has to be explicit, and if that's the case, it takes very little work to use a proper type (and properly model your problem). Sloppy code is rather common, and that's a sad state of affairs, but what does it have to do with the language? Under no circumstances should the language get involved in making sloppy code easier -- Ada's core is strong typing and we have come to regret many of the times that we've deviated (i.e. anonymous access types). > That may be one of the > big reasons why people use subtypes, rather than new types in a lot of > cases, because it fits better with the iterator types that are being > used. I think you're conflating two different issues here. > I am not using Long_Integer, or Long_Long_Integer directly in my code, > but rather something like; > > subtype Loop_Iteration_Index_Type is Long_Integer; This seems to be the worst of both worlds. You've got a much longer name standing in for a shorter name that you shouldn't be using explicitly in the first place. > By using a subtype, my code provides more flexibility in allowing > clients to decide whether they want to use explicit casting or not. Obviously, if your library was generic, the users would be making that decision as well. I don't see much advantage as to avoiding the generic library here, as you're still making the users use special subtype names and the like. (And if they *don't* use the special name, then they're making the kind of fragile code like that you show above. When people write stuff like that, they get what they deserve.) > If I used a new type, then I am forcing more explicit conversions > which some clients might find annoying. If you had simply used a generic, you wouldn't even have the question. And users could be good and use a new type, or bad and use a type from Standard, and make their own decisions. Ada 83 solved this particular problem, and nothing better has ever appeared (in any language so far as I know). What you're talking about sounds like a return to the bad old days. As I noted earlier, I could see a special non-generic version for Integer, but there doesn't seem to be any point for other types. And I don't see any language change that is needed, unless the rest of the ARG suddenly decided that they wanted to force 64-bit types down everybody's throats. I don't expect that to happen, and it certainly has nothing to do with the question of how to interface to certain C99 predefined types. **************************************************************** From: Brad Moore Sent: Thursday, March 31, 2016 8:40 AM > Please don't confuse topics. They're only vaguely related. Sorry, I should probably create a separate topic for this, but probably only worth doing so, if I can convince myself of the need. The problem I presented is itself not compelling enough to introduce a change. It's more that I might have used such a type if it existed in the standard. But I think what I really wanted is some way to use a type that can take advantage of the maximum range of integers on the target architecture, while being portable. I think the best way to do that, would instead be to create my own type based on System.Min_Int and System.Max_Int, such as; type Big_Num is range System.Min_Int .. System.Max_Int; Given this, I think the issues I presented can be dropped. More below... > > ... >> As more Ada 2012 compilers come available, more can move to the 2012 >> source baseline. > > Sure, but this is Ada 202x at the earliest. That's a *new* flavor of > Ada beyond the ones we already have. Even if you have some new > portability there, it sure as heck won't change what is available in > any of the older versions. True enough. > > ... >>> Long_Long_Integer is not portable (it's not required, and in fact it >>> is supposed to be rejected by Restriction > No_Implementation_Identifiers). >> >> Maybe Long_Long_Integer wouldn't need to be required to be minimum 64 >> bits, but rather at least as long as Long_Integer, similar to how >> Long_Integer doesn't need to be more bits than Integer. There may be >> good reasons why that isn't workable, but it strikes me as maybe >> being a better option than leaving it to be implementation defined. > > Names like Long_Long_Integer and Wide_Wide_Character are abominations > that should not in the Standard the first place. They're obtrusive, > emphasize the wrong thing, and scale badly (even while it appears > obvious -- is it really easy to tell between Long_Long_Integer and > Long_Long_Long_Integer?? 128-bit types seem inevitable.) I'm against > any expansion of the use of names like these. I agree that this naming convention is not a good one. If we really wanted a type name for something that is specifically 64 and 124 bits, something like; Integer_64 and Integer_124 would probably be better choices. But we actually already have such types in the standard package Interfaces. RM B.2 (7-8) has the following Implementation Requirements; "An implementation shall provide the following declarations in the visible part of package Interfaces: Signed and modular integer types of n bits, if supported by the target architecture, for each n that is at least the size of a storage element and that is a factor of the word size. The names of these types are of the form Integer_n for the signed types, and Unsigned_n for the modular types; " So if the compiler conforms to Annex B, it suggests that Integer_64 would need to be defined if that is the word size of the target architecture. I think this answers the need that I was presenting. For the case of interfacing to C, maybe a 64 bit integer type could be provided by using similar wording such that it is supported only if it is a factor of the word size for the target architecture. ... >> In my case, my goal is to provide some library calls, without >> using generics, where the library calls are to be potentially >> retrofitted into existing code in some cases. The intent is >> to have it so the library calls as much as possible, can be >> inserted with a minimum amount of change to the existing code. > > This problem seems to be the exact reason that generics were invented. Any > Ada user would expect to instantiate a generic (just like you need to do > that to get I/O, or a container, or pretty much anything else useful). > > Unless you are trying to code for Janus/Ada, generics don't even have any > significant runtime cost, so it's hard for me to see a good reason to avoid > them. (And for Janus/Ada, you can get much smaller code by using a common > generic that is instantiated a bunch of times.) In my case there are good reasons on both sides, which is why I have both generic and non-generic libraries. The advantages for the generic libraries include the ones that you mention. For non-generic however there are the following benefits for the case of parallelism loop libraries. 1) Easier to support multiple reductions in the same loop. This is hard to describe without going into a lot of detail, so I wont bother here. With Generics, suffice it to say that you need to provide the type of the reduction, and the reduction operation subprogram. This doesn't scale well if multiple reductions are involved. One could consider passing in arrays of class wide types, but it adds a lot of complexity. 2) Non-Generic libraries can be distributed in binary form, with or without source code. 3) Non-Generic libraries can be called from other languages. ... >> If one has the loop... >> >> declare >> subtype My_Integer is Integer; >> Sum : My_Integer := 0; >> begin >> for I in 1 .. 10 loop >> Sum := Sum + I; >> end loop; >> end; >> >> This compiles of course. >> >> But, if the declaration for My_Integer is changed to; >> type My_Integer is new Integer, then the code no longer compiles, >> as explicit conversions are needed to add I to Sum. > > This is a red herring: > (1) If you change subtype My_Integer to "is Long_Integer", the loop doesn't > compile anymore, either. The type-free iterator is a special case for type > Integer only. I can see your library for the special case of type Integer > (only); otherwise it pretty much has to be generic. I found this surprising to me. i.e. That one cannot write: for I in 1 .. 8_000_000_000 loop ... end loop; But, as you say, can be remedied with a type conversion such as; for I in 1 .. Big_Num (8_000_000_000) loop .... end loop; **************************************************************** From: Jean-Pierre Rosen Sent: Thursday, March 31, 2016 3:14 AM > The question I have is about the cost of *requiring* long_long_int in > Interfaces.C, as that appears to force 64-bit math regardless of the target. > I'm surely not against *allowing* or even *encouraging* (i.e. > Implementation > Advice) long_long_int in Interfaces.C. Seems to me that the reasonable compromise to handle this would be to put all types from the C standard in Interfaces.C, with an implementation permission to omit some types if they are not supported by the C compiler you are interfacing to. **************************************************************** From: Randy Brukardt Sent: Monday, August 1, 2016 11:47 PM Another for-the-record note. In Pisa, we said that the wording (Implementation Advice) for this AI is: An implementation should provide unsigned_long_long and long_long as 64-bit types if the C implementation supports unsigned long long and long long as 64-bit types. I think this is a bit sloppy, in that it doesn't define the kind of types nor where the types ought to be provided. We can do that with just a few extra words: An implementation should provide unsigned_long_long and long_long as 64-bit modular and signed integer types (respectively) in package Interfaces.C if the C implementation supports unsigned long long and long long as 64-bit types. Probably not something that most implementers would get wrong, but why leave it to chance? **************************************************************** From: Jeff Cousins Sent: Tuesday, August 2, 2016 1:35 AM Seems better. **************************************************************** From: Tucker Taft Sent: Tuesday, August 2, 2016 4:32 PM Your suggestions are fine by me. ****************************************************************