* Problem using Ada.Text_IO.Modular_IO @ 2008-07-09 16:52 jujosei 2008-07-09 19:03 ` Anh Vo ` (2 more replies) 0 siblings, 3 replies; 27+ messages in thread From: jujosei @ 2008-07-09 16:52 UTC (permalink / raw) Dear All, I'm tying to print variables of a defined modular type to the standard io and a file. The type I'm working with is: type Unsigned is mod 2**64; Therefore I define a modular_io package to do this: package mio is new ada.text_io.modular_io(usigned); However, when compile my little test program (using gnatmake -gnato), the compiler tells me that a "Constraint Error" will be raised at runtime. So I tried it with only 63 bit (mod 2**63), which works fine with the GNAT 4.3.1 (20080420) on a 32bit Ubuntu-Linux machine. ----------- test program ----------- with ada.text_io; use ada.text_io; procedure test is type Unsigned is mod 2**64; package M_IO is new Ada.Text_IO.Modular_IO (Unsigned); u : Unsigned := -1; begin m_io.put(Item => u, Width => 20, Base => 16); end; ----------------------------------------- I guess that this is a bug. However, what can I do instead of this, to get 64 bit words printed as hex, octal and binary? Thanks in advance! Cheers Julian Seifert ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-09 16:52 Problem using Ada.Text_IO.Modular_IO jujosei @ 2008-07-09 19:03 ` Anh Vo 2008-07-09 19:22 ` Adam Beneschan 2008-07-09 21:50 ` Adam Beneschan 2008-07-10 0:48 ` anon 2 siblings, 1 reply; 27+ messages in thread From: Anh Vo @ 2008-07-09 19:03 UTC (permalink / raw) On Jul 9, 9:52 am, jujo...@googlemail.com wrote: > Dear All, > > I'm tying to print variables of a defined modular type to the standard > io and a file. > The type I'm working with is: type Unsigned is mod 2**64; > > Therefore I define a modular_io package to do this: > package mio is new ada.text_io.modular_io(usigned); > > However, when compile my little test program (using gnatmake -gnato), > the compiler tells me that a "Constraint Error" will be raised at > runtime. So I tried it with only 63 bit (mod 2**63), which works fine > with the GNAT 4.3.1 (20080420) on a 32bit Ubuntu-Linux machine. > > ----------- test program ----------- > with ada.text_io; use ada.text_io; > procedure test is > type Unsigned is mod 2**64; > package M_IO is new Ada.Text_IO.Modular_IO (Unsigned); > u : Unsigned := -1; > begin > m_io.put(Item => u, Width => 20, Base => 16); > end; > ----------------------------------------- > > I guess that this is a bug. However, what can I do instead of this, to > get 64 bit words printed as hex, octal and binary? If you make u a constant Unsigned, it works as intended. Is it a bug as far as GNAT is concerned? I am not so sure about it. I need to check the LRM thouroughly before drawing my conclusion. AV ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-09 19:03 ` Anh Vo @ 2008-07-09 19:22 ` Adam Beneschan 0 siblings, 0 replies; 27+ messages in thread From: Adam Beneschan @ 2008-07-09 19:22 UTC (permalink / raw) On Jul 9, 12:03 pm, Anh Vo <anhvofrc...@gmail.com> wrote: > On Jul 9, 9:52 am, jujo...@googlemail.com wrote: > > > > > Dear All, > > > I'm tying to print variables of a defined modular type to the standard > > io and a file. > > The type I'm working with is: type Unsigned is mod 2**64; > > > Therefore I define a modular_io package to do this: > > package mio is new ada.text_io.modular_io(usigned); > > > However, when compile my little test program (using gnatmake -gnato), > > the compiler tells me that a "Constraint Error" will be raised at > > runtime. So I tried it with only 63 bit (mod 2**63), which works fine > > with the GNAT 4.3.1 (20080420) on a 32bit Ubuntu-Linux machine. > > > ----------- test program ----------- > > with ada.text_io; use ada.text_io; > > procedure test is > > type Unsigned is mod 2**64; > > package M_IO is new Ada.Text_IO.Modular_IO (Unsigned); > > u : Unsigned := -1; > > begin > > m_io.put(Item => u, Width => 20, Base => 16); > > end; > > ----------------------------------------- > > > I guess that this is a bug. However, what can I do instead of this, to > > get 64 bit words printed as hex, octal and binary? > > If you make u a constant Unsigned, it works as intended. Is it a bug > as far as GNAT is concerned? I am not so sure about it. I need to > check the LRM thouroughly before drawing my conclusion. This works for me: with ada.text_io; use ada.text_io; procedure test is type Unsigned is mod 2**64; function Foo return Unsigned is begin return -1; end Foo; package M_IO is new Ada.Text_IO.Modular_IO (Unsigned); u : Unsigned; begin u := Foo; m_io.put(Item => u, Width => 20, Base => 16); end; Not only does this not display a warning about Constraint_Error, it also doesn't raise Constraint_Error when it's run (and it displays the correct output). But replacing "u := Foo" with "u := -1" or "u := Unsigned'Last" does display the warning, and it does raise Constraint_Error at runtime, presumably because the compiler is doing some value following and has gotten it into its head that Unsigned'Last is out of range for the parameter of Put. No need to check the RM on this one: it's just a bug, period. But this may give the original poster an idea of a workaround. -- Adam ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-09 16:52 Problem using Ada.Text_IO.Modular_IO jujosei 2008-07-09 19:03 ` Anh Vo @ 2008-07-09 21:50 ` Adam Beneschan 2008-07-10 15:00 ` jujosei 2008-07-10 0:48 ` anon 2 siblings, 1 reply; 27+ messages in thread From: Adam Beneschan @ 2008-07-09 21:50 UTC (permalink / raw) On Jul 9, 9:52 am, jujo...@googlemail.com wrote: > Dear All, > > I'm tying to print variables of a defined modular type to the standard > io and a file. > The type I'm working with is: type Unsigned is mod 2**64; > > Therefore I define a modular_io package to do this: > package mio is new ada.text_io.modular_io(usigned); > > However, when compile my little test program (using gnatmake -gnato), > the compiler tells me that a "Constraint Error" will be raised at > runtime. So I tried it with only 63 bit (mod 2**63), which works fine > with the GNAT 4.3.1 (20080420) on a 32bit Ubuntu-Linux machine. > > ----------- test program ----------- > with ada.text_io; use ada.text_io; > procedure test is > type Unsigned is mod 2**64; > package M_IO is new Ada.Text_IO.Modular_IO (Unsigned); > u : Unsigned := -1; > begin > m_io.put(Item => u, Width => 20, Base => 16); > end; > ----------------------------------------- > > I guess that this is a bug. However, what can I do instead of this, to > get 64 bit words printed as hex, octal and binary? Here's an even simpler workaround than my last suggestion: After the declaration of "u", just add this: pragma Volatile (u); This prevents the compiler from thinking it knows what "u" is going to hold, and everything works fine. Of course, in real-life code, you're a lot more likely to using "put" on a value that the compiler won't be able to determine at compile time, so the above bug isn't going to appear anyway and you don't need a workaround. -- Adam ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-09 21:50 ` Adam Beneschan @ 2008-07-10 15:00 ` jujosei 0 siblings, 0 replies; 27+ messages in thread From: jujosei @ 2008-07-10 15:00 UTC (permalink / raw) On Jul 9, 11:50 pm, Adam Beneschan <a...@irvine.com> wrote: > On Jul 9, 9:52 am, jujo...@googlemail.com wrote: > > > > > Dear All, > > > I'm tying to print variables of a defined modular type to the standard > > io and a file. > > The type I'm working with is: type Unsigned is mod 2**64; > > > Therefore I define a modular_io package to do this: > > package mio is new ada.text_io.modular_io(usigned); > > > However, when compile my little test program (using gnatmake -gnato), > > the compiler tells me that a "Constraint Error" will be raised at > > runtime. So I tried it with only 63 bit (mod 2**63), which works fine > > with the GNAT 4.3.1 (20080420) on a 32bit Ubuntu-Linux machine. > > > ----------- test program ----------- > > with ada.text_io; use ada.text_io; > > procedure test is > > type Unsigned is mod 2**64; > > package M_IO is new Ada.Text_IO.Modular_IO (Unsigned); > > u : Unsigned := -1; > > begin > > m_io.put(Item => u, Width => 20, Base => 16); > > end; > > ----------------------------------------- > > > I guess that this is a bug. However, what can I do instead of this, to > > get 64 bit words printed as hex, octal and binary? > > Here's an even simpler workaround than my last suggestion: After the > declaration of "u", just add this: > > pragma Volatile (u); > > This prevents the compiler from thinking it knows what "u" is going to > hold, and everything works fine. Of course, in real-life code, you're > a lot more likely to using "put" on a value that the compiler won't be > able to determine at compile time, so the above bug isn't going to > appear anyway and you don't need a workaround. > > -- Adam Thank you Adam, pragma Volatile (u); is perfect! Cheers Julian ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-09 16:52 Problem using Ada.Text_IO.Modular_IO jujosei 2008-07-09 19:03 ` Anh Vo 2008-07-09 21:50 ` Adam Beneschan @ 2008-07-10 0:48 ` anon 2008-07-10 1:52 ` Adam Beneschan 2 siblings, 1 reply; 27+ messages in thread From: anon @ 2008-07-10 0:48 UTC (permalink / raw) Your code works fine for me, but using the Interfaces package is a more standardize: for unsigned 64-bits -- -- test.adb -- with ada.text_io ; use ada.text_io ; with Interfaces ; -- Defines Unsigned_64 use Interfaces ; procedure test is -- -- Interfaces define the following: -- -- type Unsigned_64 is mod 2 ** 64; -- for Unsigned_64'Size use 64; -- You may need to add this type -- -- of statement to your version -- package M_IO is new Ada.Text_IO.Modular_IO ( Unsigned_64 ) ; c : constant Unsigned_64 := -5 ; -- Must declare type with a "constant" -- statement u : Unsigned_64 := -1 ; begin m_io.put ( Item => u, Width => 20, Base => 16 ) ; new_line ; -- -- using a constant -- m_io.put ( Item => c, Width => 20, Base => 16 ) ; new_line ; end ; In <4eab7055-df3d-4d56-87da-8248829da1da@26g2000hsk.googlegroups.com>, jujosei@googlemail.com writes: >Dear All, > >I'm tying to print variables of a defined modular type to the standard >io and a file. >The type I'm working with is: type Unsigned is mod 2**64; > >Therefore I define a modular_io package to do this: >package mio is new ada.text_io.modular_io(usigned); > >However, when compile my little test program (using gnatmake -gnato), >the compiler tells me that a "Constraint Error" will be raised at >runtime. So I tried it with only 63 bit (mod 2**63), which works fine >with the GNAT 4.3.1 (20080420) on a 32bit Ubuntu-Linux machine. > >----------- test program ----------- >with ada.text_io; use ada.text_io; >procedure test is > type Unsigned is mod 2**64; > package M_IO is new Ada.Text_IO.Modular_IO (Unsigned); > u : Unsigned := -1; >begin > m_io.put(Item => u, Width => 20, Base => 16); >end; >----------------------------------------- > >I guess that this is a bug. However, what can I do instead of this, to >get 64 bit words printed as hex, octal and binary? > >Thanks in advance! >Cheers >Julian Seifert ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-10 0:48 ` anon @ 2008-07-10 1:52 ` Adam Beneschan 2008-07-10 7:25 ` anon 0 siblings, 1 reply; 27+ messages in thread From: Adam Beneschan @ 2008-07-10 1:52 UTC (permalink / raw) On Jul 9, 5:48 pm, a...@anon.org (anon) wrote: > Your code works fine for me, but using the Interfaces package is a > more standardize: for unsigned 64-bits > > -- > -- test.adb > -- > with ada.text_io ; > use ada.text_io ; > > with Interfaces ; -- Defines Unsigned_64 > use Interfaces ; But why would he want to use Interfaces if he's not interfacing to anything? -- Adam ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-10 1:52 ` Adam Beneschan @ 2008-07-10 7:25 ` anon 2008-07-10 14:59 ` Adam Beneschan 0 siblings, 1 reply; 27+ messages in thread From: anon @ 2008-07-10 7:25 UTC (permalink / raw) It is easy to use and is tested and verified to work! To name one to two reasons! In <afdd91d0-910b-4f28-a18d-d85da90f20fc@x41g2000hsb.googlegroups.com>, Adam Beneschan <adam@irvine.com> writes: >On Jul 9, 5:48 pm, a...@anon.org (anon) wrote: >> Your code works fine for me, but using the Interfaces package is a >> more standardize: for unsigned 64-bits >> >> -- >> -- test.adb >> -- >> with ada.text_io ; >> use ada.text_io ; >> >> with Interfaces ; -- Defines Unsigned_64 >> use Interfaces ; > >But why would he want to use Interfaces if he's not interfacing to >anything? > > -- Adam > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-10 7:25 ` anon @ 2008-07-10 14:59 ` Adam Beneschan 2008-07-11 0:34 ` anon 0 siblings, 1 reply; 27+ messages in thread From: Adam Beneschan @ 2008-07-10 14:59 UTC (permalink / raw) On Jul 10, 12:25 am, a...@anon.org (anon) wrote: > It is easy to use and is tested and verified to work! To name one to > two reasons! Those don't seem like much of a reason. Declaring your own type as "mod 2**64" seems pretty darn easy. And what exactly do you mean by Unsigned_64 is "tested"? Unsigned_64 is simply declared as "mod 2**64" (this is specified by the language); so are you saying that operations on Unsigned_64 have been tested and have found to work right, but if you declare your own "mod 2**64" you have to do your own testing to make sure that operations on it work right? I'm having trouble interpreting your comment in a way that makes any sense. Of course, it really doesn't matter which one you use (except, perhaps, to help prevent incorrect type conversions). The only differences have to do with readability, pedagogy, and helping make your programs self-documenting. But ever since Ada was designed, the position of the Ada community has been that it's better to avoid using the standard numeric types provided by Ada (Integer, Float) and define your own that explicitly include the numeric range you need. You seem to be going in the opposite direction, by recommending that this user use a standard type provided by the language rather than defining his own (although the standard type you recommend is certainly better defined than Integer or Float). Another issue is that an implementation doesn't have to provide Interfaces.Unsigned_64. It should be present on any target processor whose addressable unit is an 8-bit byte or a 16-, 32-, or 64-bit word. But I've seen processors in the past that use 6-bit characters or 36-bit words, and in those cases, using Unsigned_64 instead of "mod 2**64" will turn a portable program into a nonportable one. I'll grant that such processors are rare these days. -- Adam ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-10 14:59 ` Adam Beneschan @ 2008-07-11 0:34 ` anon 2008-07-11 9:49 ` Georg Bauhaus 0 siblings, 1 reply; 27+ messages in thread From: anon @ 2008-07-11 0:34 UTC (permalink / raw) Why re-invent the Wheel!!! If we spend all day re-stating that which has been done then nothing new get done that day! Just like Wash., which is a place where nothing get done except to find ways to seprate the people from their money, by doing nothing at all. In <32e35e5a-3cae-4fdc-be4a-3ae1e146e9f3@l64g2000hse.googlegroups.com>, Adam Beneschan <adam@irvine.com> writes: >On Jul 10, 12:25 am, a...@anon.org (anon) wrote: >> It is easy to use and is tested and verified to work! To name one to >> two reasons! > >Those don't seem like much of a reason. Declaring your own type as >"mod 2**64" seems pretty darn easy. And what exactly do you mean by >Unsigned_64 is "tested"? Unsigned_64 is simply declared as "mod >2**64" (this is specified by the language); so are you saying that >operations on Unsigned_64 have been tested and have found to work >right, but if you declare your own "mod 2**64" you have to do your own >testing to make sure that operations on it work right? I'm having >trouble interpreting your comment in a way that makes any sense. > >Of course, it really doesn't matter which one you use (except, >perhaps, to help prevent incorrect type conversions). The only >differences have to do with readability, pedagogy, and helping make >your programs self-documenting. But ever since Ada was designed, the >position of the Ada community has been that it's better to avoid using >the standard numeric types provided by Ada (Integer, Float) and define >your own that explicitly include the numeric range you need. You seem >to be going in the opposite direction, by recommending that this user >use a standard type provided by the language rather than defining his >own (although the standard type you recommend is certainly better >defined than Integer or Float). > >Another issue is that an implementation doesn't have to provide >Interfaces.Unsigned_64. It should be present on any target processor >whose addressable unit is an 8-bit byte or a 16-, 32-, or 64-bit >word. But I've seen processors in the past that use 6-bit characters >or 36-bit words, and in those cases, using Unsigned_64 instead of "mod >2**64" will turn a portable program into a nonportable one. I'll >grant that such processors are rare these days. > > -- Adam > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-11 0:34 ` anon @ 2008-07-11 9:49 ` Georg Bauhaus 2008-07-11 10:05 ` christoph.grein 2008-07-11 12:16 ` anon 0 siblings, 2 replies; 27+ messages in thread From: Georg Bauhaus @ 2008-07-11 9:49 UTC (permalink / raw) anon wrote: > Why re-invent the Wheel!!! If we spend all day re-stating that which > has been done then nothing new get done that day! As Adam is pointing out below---in two paragraphs which I think are really recommended reading---Unsigned_64 is defined for a specific programming context. Typically that of interfacing to 2**N bit addressable hardware, N >= 3. When a program does not perform any interfacing, but still uses types from Interfaces, then in a sense its use of type is close to C's approach to the fundamental type system: In C, you have fundamental "scalar" types that say, "at least that many bits, some operations, some behavior at the bounds, and please look up the rest in the compiler's documentation". When Ada allows the programmer to work at a higher level of type isolation and expressiveness, without loosing any performance, not having to consult compiler docs, isn't this a win? I recall a c.l.ada message from a university teacher of embedded systems programming (model trains, I think) whose classes had switched from C to Ada. After that, the students had achieved more and got better results. The effect was attributed to Ada's fundamental type system and types defined in terms of the (abstracted) problem domain. I.e., not just Interfaces. > In <32e35e5a-3cae-4fdc-be4a-3ae1e146e9f3@l64g2000hse.googlegroups.com>, Adam Beneschan <adam@irvine.com> writes: >> Of course, it really doesn't matter which one you use (except, >> perhaps, to help prevent incorrect type conversions). The only >> differences have to do with readability, pedagogy, and helping make >> your programs self-documenting. But ever since Ada was designed, the >> position of the Ada community has been that it's better to avoid using >> the standard numeric types provided by Ada (Integer, Float) and define >> your own that explicitly include the numeric range you need. You seem >> to be going in the opposite direction, by recommending that this user >> use a standard type provided by the language rather than defining his >> own (although the standard type you recommend is certainly better >> defined than Integer or Float). >> >> Another issue is that an implementation doesn't have to provide >> Interfaces.Unsigned_64. It should be present on any target processor >> whose addressable unit is an 8-bit byte or a 16-, 32-, or 64-bit >> word. But I've seen processors in the past that use 6-bit characters >> or 36-bit words, and in those cases, using Unsigned_64 instead of "mod >> 2**64" will turn a portable program into a nonportable one. I'll >> grant that such processors are rare these days. >> >> -- Adam >> > -- Georg Bauhaus Y A Time Drain http://www.9toX.de ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-11 9:49 ` Georg Bauhaus @ 2008-07-11 10:05 ` christoph.grein 2008-07-11 13:21 ` John McCormick 2008-07-11 12:16 ` anon 1 sibling, 1 reply; 27+ messages in thread From: christoph.grein @ 2008-07-11 10:05 UTC (permalink / raw) > I recall a c.l.ada message from a university teacher of embedded > systems programming (model trains, I think) whose classes had > switched from C to Ada. After that, the students had achieved more > and got better results. The effect was attributed to Ada's > fundamental type system and types defined in terms of the > (abstracted) problem domain. I.e., not just Interfaces. John W. McCormick Software Engineering Education: On the Right Track (On Crosstalk Aug 2000) Most impressive paper. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-11 10:05 ` christoph.grein @ 2008-07-11 13:21 ` John McCormick 0 siblings, 0 replies; 27+ messages in thread From: John McCormick @ 2008-07-11 13:21 UTC (permalink / raw) On Jul 11, 5:05 am, christoph.gr...@eurocopter.com wrote: > > I recall a c.l.ada message from a university teacher of embedded > > systems programming (model trains, I think) whose classes had > > switched from C to Ada. After that, the students had achieved more > > and got better results. The effect was attributed to Ada's > > fundamental type system and types defined in terms of the > > (abstracted) problem domain. I.e., not just Interfaces. > > John W. McCormick > Software Engineering Education: On the Right Track > > (On Crosstalk Aug 2000) > > Most impressive paper. Thanks for the compliment. Georg is correct about my attributing student success to types defined in terms of the problem domain. Here is a link to the Crosstalk paper http://www.stsc.hill.af.mil/crosstalk/2000/08/mccormick.html I discussed this work on an education panel held at Ada Europe last month. I also showed a 13 minute video of the work done by my students. A streaming version of that video is available on my lab page http://www.cs.uni.edu/~mccormic/RealTime/ John ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-11 9:49 ` Georg Bauhaus 2008-07-11 10:05 ` christoph.grein @ 2008-07-11 12:16 ` anon 2008-07-11 13:26 ` petter_fryklund 1 sibling, 1 reply; 27+ messages in thread From: anon @ 2008-07-11 12:16 UTC (permalink / raw) I did not comment Adam's two paragraphs because I did not want to cut him down. Now, UNISYS at one time used 9-bit/18/36-bits (power of 3) instead of power of 2. But the norm for todays computers is base 2, that's is the only reason the specs only use 2**N instead of including 3**N for UNISYS. If you look at RM B.2 (7-8) which suggest that if the "target architecture" support N-bits words then the "implementation shall provide" that defintion in both signed and modular types. [ I think Adam forgot to look at that one. ] Since, most system today sopport 8/16/32 and 64-bit words then the "Interfaces" package shall contain definitions for those words. And since vendor has done the work for us, so why not use it. But my main point is that you should know what is in the packages on the system that you are using and how they work. And if they save time in creating a partition then use them. Plus, as for compatibility with other Ada vendors or future GNAT versions, well my talks with Adacore over the death of GLADE suggest that they do not care for the term "compatibility " any more. Also, if we do not use each part of the GNAT Ada package it might disappear in the next specification version of Ada. Which may come out sooner than we think, just an idea that came from my talks with Adacore. In <48772c92$0$6601$9b4e6d93@newsspool2.arcor-online.net>, Georg Bauhaus <see.reply.to@maps.futureapps.de> writes: >anon wrote: >> Why re-invent the Wheel!!! If we spend all day re-stating that which >> has been done then nothing new get done that day! > > >As Adam is pointing out below---in two paragraphs which I think >are really recommended reading---Unsigned_64 is defined for a >specific programming context. Typically that of interfacing >to 2**N bit addressable hardware, N >= 3. > >When a program does not perform any interfacing, but still >uses types from Interfaces, then in a sense its use of type is >close to C's approach to the fundamental type system: >In C, you have fundamental "scalar" types that say, >"at least that many bits, some operations, some behavior at the >bounds, and please look up the rest in the compiler's >documentation". When Ada allows the programmer to work at a >higher level of type isolation and expressiveness, without loosing >any performance, not having to consult compiler docs, >isn't this a win? > >I recall a c.l.ada message from a university teacher of embedded >systems programming (model trains, I think) whose classes had >switched from C to Ada. After that, the students had achieved more >and got better results. The effect was attributed to Ada's >fundamental type system and types defined in terms of the >(abstracted) problem domain. I.e., not just Interfaces. > > >> In <32e35e5a-3cae-4fdc-be4a-3ae1e146e9f3@l64g2000hse.googlegroups.com>, Adam Beneschan <adam@irvine.com> writes: > >>> Of course, it really doesn't matter which one you use (except, >>> perhaps, to help prevent incorrect type conversions). The only >>> differences have to do with readability, pedagogy, and helping make >>> your programs self-documenting. But ever since Ada was designed, the >>> position of the Ada community has been that it's better to avoid using >>> the standard numeric types provided by Ada (Integer, Float) and define >>> your own that explicitly include the numeric range you need. You seem >>> to be going in the opposite direction, by recommending that this user >>> use a standard type provided by the language rather than defining his >>> own (although the standard type you recommend is certainly better >>> defined than Integer or Float). >>> >>> Another issue is that an implementation doesn't have to provide >>> Interfaces.Unsigned_64. It should be present on any target processor >>> whose addressable unit is an 8-bit byte or a 16-, 32-, or 64-bit >>> word. But I've seen processors in the past that use 6-bit characters >>> or 36-bit words, and in those cases, using Unsigned_64 instead of "mod >>> 2**64" will turn a portable program into a nonportable one. I'll >>> grant that such processors are rare these days. >>> >>> -- Adam >>> >> > >-- >Georg Bauhaus >Y A Time Drain http://www.9toX.de ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-11 12:16 ` anon @ 2008-07-11 13:26 ` petter_fryklund 2008-07-11 21:10 ` anon 0 siblings, 1 reply; 27+ messages in thread From: petter_fryklund @ 2008-07-11 13:26 UTC (permalink / raw) On 11 Juli, 14:16, a...@anon.org (anon) wrote: > I did not comment Adam's two paragraphs because I did not want to cut > him down. > > Now, UNISYS at one time used 9-bit/18/36-bits (power of 3) instead of > power of 2. But the norm for todays computers is base 2, that's is the > only reason the specs only use 2**N instead of including 3**N for UNISYS. > > If you look at RM B.2 (7-8) which suggest that if the "target architecture" > support N-bits words then the "implementation shall provide" that > defintion in both signed and modular types. [ I think Adam forgot to look > at that one. ] Since, most system today sopport 8/16/32 and 64-bit words > then the "Interfaces" package shall contain definitions for those words. > And since vendor has done the work for us, so why not use it. > > But my main point is that you should know what is in the packages on > the system that you are using and how they work. And if they save time > in creating a partition then use them. > > Plus, as for compatibility with other Ada vendors or future GNAT versions, > well my talks with Adacore over the death of GLADE suggest that they do > not care for the term "compatibility " any more. Also, if we do not use > each part of the GNAT Ada package it might disappear in the next > specification version of Ada. Which may come out sooner than we think, > just an idea that came from my talks with Adacore. > > In <48772c92$0$6601$9b4e6...@newsspool2.arcor-online.net>, Georg Bauhaus <see.reply...@maps.futureapps.de> writes: > > > > >anon wrote: > >> Why re-invent the Wheel!!! If we spend all day re-stating that which > >> has been done then nothing new get done that day! > > >As Adam is pointing out below---in two paragraphs which I think > >are really recommended reading---Unsigned_64 is defined for a > >specific programming context. Typically that of interfacing > >to 2**N bit addressable hardware, N >= 3. > > >When a program does not perform any interfacing, but still > >uses types from Interfaces, then in a sense its use of type is > >close to C's approach to the fundamental type system: > >In C, you have fundamental "scalar" types that say, > >"at least that many bits, some operations, some behavior at the > >bounds, and please look up the rest in the compiler's > >documentation". When Ada allows the programmer to work at a > >higher level of type isolation and expressiveness, without loosing > >any performance, not having to consult compiler docs, > >isn't this a win? > > >I recall a c.l.ada message from a university teacher of embedded > >systems programming (model trains, I think) whose classes had > >switched from C to Ada. After that, the students had achieved more > >and got better results. The effect was attributed to Ada's > >fundamental type system and types defined in terms of the > >(abstracted) problem domain. I.e., not just Interfaces. > > >> In <32e35e5a-3cae-4fdc-be4a-3ae1e146e...@l64g2000hse.googlegroups.com>, Adam Beneschan <a...@irvine.com> writes: > > >>> Of course, it really doesn't matter which one you use (except, > >>> perhaps, to help prevent incorrect type conversions). The only > >>> differences have to do with readability, pedagogy, and helping make > >>> your programs self-documenting. But ever since Ada was designed, the > >>> position of the Ada community has been that it's better to avoid using > >>> the standard numeric types provided by Ada (Integer, Float) and define > >>> your own that explicitly include the numeric range you need. You seem > >>> to be going in the opposite direction, by recommending that this user > >>> use a standard type provided by the language rather than defining his > >>> own (although the standard type you recommend is certainly better > >>> defined than Integer or Float). > > >>> Another issue is that an implementation doesn't have to provide > >>> Interfaces.Unsigned_64. It should be present on any target processor > >>> whose addressable unit is an 8-bit byte or a 16-, 32-, or 64-bit > >>> word. But I've seen processors in the past that use 6-bit characters > >>> or 36-bit words, and in those cases, using Unsigned_64 instead of "mod > >>> 2**64" will turn a portable program into a nonportable one. I'll > >>> grant that such processors are rare these days. > > >>> -- Adam > > >-- > >Georg Bauhaus > >Y A Time Drainhttp://www.9toX.de- Dölj citerad text - > > - Visa citerad text - Well the word length on UNISYS (SPERRY) has nothing to do with power of three. A word could also be 6x6 bits. Or can, there are still some UNISYS equipment around. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-11 13:26 ` petter_fryklund @ 2008-07-11 21:10 ` anon 2008-07-12 10:06 ` Georg Bauhaus 0 siblings, 1 reply; 27+ messages in thread From: anon @ 2008-07-11 21:10 UTC (permalink / raw) But like the rest you miss the point. "KNOW and USE your Ada System and stop wasting time reventing types or routines!" And USE as much of the system as you can or it may not be there tomorrow, when you really need it!" In <867127d8-3b21-40dd-bb76-f19cd349b21e@26g2000hsk.googlegroups.com>, petter_fryklund@hotmail.com writes: >On 11 Juli, 14:16, a...@anon.org (anon) wrote: >> I did not comment Adam's two paragraphs because I did not want to cut >> him down. >> >> Now, UNISYS at one time used 9-bit/18/36-bits (power of 3) instead of >> power of 2. But the norm for todays computers is base 2, that's is the >> only reason the specs only use 2**N instead of including 3**N for UNISYS. >> >> If you look at RM B.2 (7-8) which suggest that if the "target architectur= >e" >> support N-bits words then the "implementation shall provide" that >> defintion in both signed and modular types. [ I think Adam forgot to look >> at that one. ] Since, most system today sopport 8/16/32 and 64-bit words >> then the "Interfaces" package shall contain definitions for those words. >> And since vendor has done the work for us, so why not use it. >> >> But my main point is that you should know what is in the packages on >> the system that you are using and how they work. And if they save time >> in creating a partition then use them. >> >> Plus, as for compatibility with other Ada vendors or future GNAT versions= >, >> well my talks with Adacore over the death of GLADE suggest that they do >> not care for the term "compatibility " any more. =A0Also, if we do not us= >e >> each part of the GNAT Ada package it might disappear in the next >> specification version of Ada. Which may come out sooner than we think, >> just an idea that came from my talks with Adacore. >> >> In <48772c92$0$6601$9b4e6...@newsspool2.arcor-online.net>, Georg Bauhaus = ><see.reply...@maps.futureapps.de> writes: >> >> >> >> >anon wrote: >> >> Why re-invent the Wheel!!! If we spend all day re-stating that which >> >> has been done then nothing new get done that day! >> >> >As Adam is pointing out below---in two paragraphs which I think >> >are really recommended reading---Unsigned_64 is defined for a >> >specific programming context. Typically that of interfacing >> >to 2**N bit addressable hardware, N >=3D 3. >> >> >When a program does not perform any interfacing, but still >> >uses types from Interfaces, then in a sense its use of type is >> >close to C's approach to the fundamental type system: >> >In C, you have fundamental "scalar" types that say, >> >"at least that many bits, some operations, some behavior at the >> >bounds, and please look up the rest in the compiler's >> >documentation". =A0When Ada allows the programmer to work at a >> >higher level of type isolation and expressiveness, without loosing >> >any performance, not having to consult compiler docs, >> >isn't this a win? >> >> >I recall a c.l.ada message from a university teacher of embedded >> >systems programming (model trains, I think) whose classes had >> >switched from C to Ada. After that, the students had achieved more >> >and got better results. The effect was attributed to Ada's >> >fundamental type system and types defined in terms of the >> >(abstracted) problem domain. =A0I.e., not just Interfaces. >> >> >> In <32e35e5a-3cae-4fdc-be4a-3ae1e146e...@l64g2000hse.googlegroups.com>= >, Adam Beneschan <a...@irvine.com> writes: >> >> >>> Of course, it really doesn't matter which one you use (except, >> >>> perhaps, to help prevent incorrect type conversions). =A0The only >> >>> differences have to do with readability, pedagogy, and helping make >> >>> your programs self-documenting. =A0But ever since Ada was designed, t= >he >> >>> position of the Ada community has been that it's better to avoid usin= >g >> >>> the standard numeric types provided by Ada (Integer, Float) and defin= >e >> >>> your own that explicitly include the numeric range you need. =A0You s= >eem >> >>> to be going in the opposite direction, by recommending that this user >> >>> use a standard type provided by the language rather than defining his >> >>> own (although the standard type you recommend is certainly better >> >>> defined than Integer or Float). >> >> >>> Another issue is that an implementation doesn't have to provide >> >>> Interfaces.Unsigned_64. =A0It should be present on any target process= >or >> >>> whose addressable unit is an 8-bit byte or a 16-, 32-, or 64-bit >> >>> word. =A0But I've seen processors in the past that use 6-bit characte= >rs >> >>> or 36-bit words, and in those cases, using Unsigned_64 instead of "mo= >d >> >>> 2**64" will turn a portable program into a nonportable one. =A0I'll >> >>> grant that such processors are rare these days. >> >> >>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0--= > Adam >> >> >-- >> >Georg Bauhaus >> >Y A Time Drainhttp://www.9toX.de- D=F6lj citerad text - >> >> - Visa citerad text - > >Well the word length on UNISYS (SPERRY) has nothing to do with power >of three. A word could also be 6x6 bits. Or can, there are still some >UNISYS equipment around. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-11 21:10 ` anon @ 2008-07-12 10:06 ` Georg Bauhaus 2008-07-13 0:51 ` anon 2008-07-13 16:03 ` Georg Bauhaus 0 siblings, 2 replies; 27+ messages in thread From: Georg Bauhaus @ 2008-07-12 10:06 UTC (permalink / raw) anon wrote: > But like the rest you miss the point. "KNOW and USE your Ada System and > stop wasting time reventing types or routines!" And USE as much of the > system as you can or it may not be there tomorrow, when you really need it!" The other point is that using an Ada system well means to know the Ada fundamental type system. Start thinking about the types that your program needs. Most of the time this means, avoid the predefined "vague" types, they are overly inclusive types, not specific to the task at hand and hence convey little meaning. You get the same speed if you define your own types, (re)using the Ada fundamental type system. If interfacing to hardware, or to other languages, use types from the Interface hierarchy. -- Georg Bauhaus Y A Time Drain http://www.9toX.de ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-12 10:06 ` Georg Bauhaus @ 2008-07-13 0:51 ` anon 2008-07-13 16:03 ` Georg Bauhaus 1 sibling, 0 replies; 27+ messages in thread From: anon @ 2008-07-13 0:51 UTC (permalink / raw) Back when there were widely use hardware with different word sizes you would need to define the type. But before Microsoft, the computer world decides to use base 2 in the following formats 8/16/32/64/128/256 with each having different problems of access time based on the cpu and data sizes.. In other words a 32-bit system has a faster time accessing a 32-bit word than accessing a 8-bit word. And has to use extra routines to simulate a 5-bit words instruction or data size. Plus, when a programmer defines their own type in Ada, Ada adds extra set of routines that are not based in hardware checks but software, which slows a program down. And when you are using sometime like "mod 2**64" which is pre-define as Unsigned_64 which can be hardware check (because it is a full 64-bit word) why would any programmer add a user defined type that would slow their program down for no reason other than to waste time, both in programming/debugging and execution time. And as any boss will tell you time is money and money is the bottom line. Or in the Gaming world the more time it take the more likely player will lose the game and the player will lose interest in the game, and stop buying the programmers game. etc. So, TIME is still a big factor to programmers. And as for defining types and let the compiler add the vendors verification routines, should ONLY happen in the classroom. If programmere define a type then they should define how and where the verification will take place not the compiler. Aka using Ravenscar type of programming. But for most programmers it seams, Ravenscar type of programmere is just too hard to use. But once you start using Ravenscar you will never go back to the old ways. In <4878820c$0$27451$9b4e6d93@newsspool4.arcor-online.net>, Georg Bauhaus <see.reply.to@maps.futureapps.de> writes: >anon wrote: >> But like the rest you miss the point. "KNOW and USE your Ada System and >> stop wasting time reventing types or routines!" And USE as much of the >> system as you can or it may not be there tomorrow, when you really need it!" > >The other point is that using an Ada system well means to know >the Ada fundamental type system. Start thinking about the types >that your program needs. Most of the time this means, avoid >the predefined "vague" types, they are overly inclusive types, >not specific to the task at hand and hence convey little meaning. >You get the same speed if you define your own types, (re)using >the Ada fundamental type system. > >If interfacing to hardware, or to other languages, use types from >the Interface hierarchy. > >-- >Georg Bauhaus >Y A Time Drain http://www.9toX.de ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-12 10:06 ` Georg Bauhaus 2008-07-13 0:51 ` anon @ 2008-07-13 16:03 ` Georg Bauhaus 2008-07-14 2:03 ` anon 2008-07-14 16:34 ` micronian2 1 sibling, 2 replies; 27+ messages in thread From: Georg Bauhaus @ 2008-07-13 16:03 UTC (permalink / raw) On Sun, 2008-07-13 at 00:51 +0000, anon wrote: > Plus, when a programmer defines their own type in Ada, Ada adds > extra set of routines that are not based in hardware checks but software, > which slows a program down. I'm not sure there is some real context here. There is no loss in speed and no cost in terms of additional checks for using either Unsigned_64 or "mod 2**64". (Or "mod 2**(something smaller)".) Below is an example to serve as one of many (really unnecessary) proofs that there is no overhead stemming from user defined types "mod 2**N". (And no overhead stemming from user defined types in general---they are there for a reason in this real-time systems programming language, I should think.) Hardware will in the end fetch words from memory etc., but what does this have to do with using a type mod 2**64 instead of using Unsigned_64? The compiler produces the code, just the compiler. Will a 64bit compiler use different intrinsic routines (such as "+") when the arguments are not Unsigned_64 but of type mod 2**64? It does *not* seem to be the case, see below. No magically different checks either. Turning checks on/off is in the hands of the compiler operator. For the code appended, I get not a single difference in object code when using "mod 2**64" or Unsigned_64. With or without optimization, neither the representation nor the instructions differ at all. Not a bit. Even using a packed array of 64 Booleans gives the very same code with -O, and a very small difference results with -O0 between the boolean array code and the scalar types code. I would have expected exactly this to be the case. Here is the machine code of subprogram Predefined which is using Unsigned_64 as an "in out" Parameter, then followed by machine code of subprogram Programmer_Defined which uses "mod 2**64". First the case with some optimization. The Ada subprogram is, basically, procedure P(Item: in out T) is begin Item := not Item; end P; where T stands for Unsigned_64 and "mod 2**64", resp. $ gnatmake -gnata -gnato -gnatwa -O -fno-inline speed.adb 0000000000000000 <speed__predefined.1692>: 0: 48 89 f8 mov %rdi,%rax 3: 48 f7 d0 not %rax 6: c3 retq 7: 90 nop 0000000000000008 <speed__programmer_defined.1700>: 8: 48 89 f8 mov %rdi,%rax b: 48 f7 d0 not %rax e: c3 retq f: 90 nop No difference. (And no checks.) Next with no optimization at all: $ gnatmake -gnata -gnato -gnatwa -O0 -fno-inline speed.adb 00000000000003c6 <speed__programmer_defined.1700>: 3c6: 55 push %rbp 3c7: 48 89 e5 mov %rsp,%rbp 3ca: 48 89 7d f8 mov %rdi,-0x8(%rbp) 3ce: 4c 89 55 f0 mov %r10,-0x10(%rbp) 3d2: 48 f7 55 f8 notq -0x8(%rbp) 3d6: 48 8b 45 f8 mov -0x8(%rbp),%rax 3da: c9 leaveq 3db: c3 retq 00000000000003dc <speed__predefined.1692>: 3dc: 55 push %rbp 3dd: 48 89 e5 mov %rsp,%rbp 3e0: 48 89 7d f8 mov %rdi,-0x8(%rbp) 3e4: 4c 89 55 f0 mov %r10,-0x10(%rbp) 3e8: 48 f7 55 f8 notq -0x8(%rbp) 3ec: 48 8b 45 f8 mov -0x8(%rbp),%rax 3f0: c9 leaveq 3f1: c3 retq No difference. (And no checks.) with Interfaces; use Interfaces; with Ada.Text_IO; use Ada.Text_IO; procedure Speed2 is -- -- Case 1: -- reusing predefined type from Interfaces: -- procedure Predefined(Item: in out Unsigned_64) is begin Item := not Item; end Predefined; -- -- Case 2: -- using a programmer defind modular type: -- type B_Set is mod 2**64; procedure Programmer_Defined(Item: in out B_Set) is begin Item := not Item; end Programmer_Defined; -- -- Case 3: -- using a different programmer defined type: -- type Bit_List is array(Positive range <>) of Boolean; pragma Pack(Bit_List); subtype B_List is Bit_List(1 .. 64); procedure Really_Programmer_Defined(Item: in out B_List) is begin Item := not Item; end Really_Programmer_Defined; -- -- IO of inputs and results -- package IO_U64 is new Ada.Text_IO.Modular_IO(Unsigned_64); package IO_B is new Ada.Text_IO.Modular_IO(B_Set); package IO_L is -- a fake IO package for hex output of boolean array `B_List` Default_Width : Ada.Text_IO.Field := Unsigned_64'Width; Default_Base : Ada.Text_IO.Number_Base := 10; procedure Put(Item: B_List; Base: Number_Base := Default_Base; Width: Field := Default_Width); end IO_L; package body IO_L is separate; begin -- Speed -- Starting with case 3. The bit values are set for position -- numbered ranges. These will become bit positions in the other -- cases. -- pragma Volatile appears to help prevent Constraint_Error for -- non-static universal integer in `Value = 16#...#` with current -- GNAT. -- case 3: Packed_Arrays: declare Value: B_List; begin Value := B_List' (1 .. 10 => True, 11 .. 27 => False, 28 .. 40 => True, 41 .. 42 => False, 43 .. 63 => True, 64 => False); Put(" As B_List: "); IO_L.Put(Value, Base => 16); New_Line; Really_Programmer_Defined(Value); Put(" As B_List: "); IO_L.Put(Value, Base => 16); New_Line; end Packed_Arrays; -- case 2: User_Mod_Types: declare Value: B_Set; pragma Volatile(Value); begin Value := 2#1111111111_00000000000000000_1111111111111_00_111111111111111111111_0#; pragma Assert(Value = 16#FFC0001FFF3FFFFE#); Put(" As B_Set: "); IO_B.Put(Value, Base => 16); New_Line; Programmer_Defined(Value); Put(" As B_Set: "); IO_B.Put(Value, Base => 16); New_Line; end User_Mod_Types; -- case 1: Interface_Types: declare Value: Unsigned_64; pragma Volatile(Value); begin Value := 2#1111111111_00000000000000000_1111111111111_00_111111111111111111111_0#; pragma Assert(Value = 16#FFC0001FFF3FFFFE#); Put("As Unsigned_64: "); IO_U64.Put(Value, Base => 16); New_Line; Predefined(Value); Put("As Unsigned_64: "); IO_U64.Put(Value, Base => 16); New_Line; end Interface_Types; end Speed2; separate(Speed2) package body IO_L is Four : constant Positive := 4; subtype B_List4 is Bit_List(1 .. Four); function To_Char(Item: B_List4) return Character is -- Character representing the `Item` as a hex digit type N8 is range 0 .. 2**Four - 1; function As_N8(Omit_First: Boolean) return N8 is -- compute `Item`'s value from bits [1,]2,3,4 independent of -- bit order Result: N8; First_Bit: constant Positive := 1 + Boolean'Pos(Omit_First); begin Result := 0; for K in First_Bit .. Four loop Result := Result + 2**(Four - K) * Boolean'Pos(Item(K)); end loop; return Result; end As_N8; begin -- To_Char if Item(1) and then (Item(2) or Item(3)) then -- hex digit A, B, ... return Character'Val(Character'Pos('A') + As_N8(Omit_First => True) - 2); else -- decimal digit return Character'Val(Character'Pos('0') + As_N8(Omit_First => False)); end if; end To_Char; procedure Put(Item: B_List; Base: Number_Base := Default_Base; Width: Field := Default_Width) is Num_Half_Bytes : constant Positive := B_List'Size / Four; Result: String(1 .. Num_Half_Bytes); begin case Base is when 16 => for J in 0 .. Num_Half_Bytes - 1 loop Result(J + 1) := To_Char(Item((J) * Four + 1 .. (J + 1) * Four)); end loop; declare Extra_Spaces: constant Natural := Positive'Max(Width - Num_Half_Bytes - 4, 0); begin Ada.Text_IO.Put(String'(1 .. Extra_Spaces => ' ') &"16#" & Result & "#"); end; when others => -- not supported raise Program_Error; end case; end Put; end IO_L; ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-13 16:03 ` Georg Bauhaus @ 2008-07-14 2:03 ` anon 2008-07-14 13:12 ` Georg Bauhaus 2008-07-14 16:34 ` micronian2 1 sibling, 1 reply; 27+ messages in thread From: anon @ 2008-07-14 2:03 UTC (permalink / raw) When the CPU or FFU executes a single arithmetic instruction it uses the build-in CPU Carry flag to detect a Overflow/Underflow condition for those types that are define in the Standard/System packages. Which is faster than a set of routines that the compiler generates for a new user type. For checking a 2**5 which is 32, the CPU can not use carry flag, so compiler has to generate a set of routines to simulate a CPU with 5-bit and will use the Constraint_Error if out of bound condition result from the arithmetic function. Actually, in the case of 2**5 the arithmetic function is done on the processor 8-bit word and then the result is compared to see if the result is with the range of 2**5. A lot of instructions are generated instead of only three for build-in types: pseudo Assembly for 2**64 built-in using Reg. 1. Load Accumator Reg with First argument 2. Preform arithmetic operation using Accumator Reg with Second in memory argument 3. Jump on Carry flag -- To set Constraint_Error condition ... And for a using a user type: 2**5 pseudo Assembly for 2**5 built-in using Reg. 1. Load Accumator Reg with First argument 2. Mast off 2**6 and 2**7 bits 3. Load Second Accumator Reg with Second argument 4. Mast off 2**6 and 2**7 bits 5. Preform arithmetic operation using both Accumator Regs 6. copy result into Temp Reg 7. Mast off 2**5 in Accumator Reg 8. Jump if not zero -- To set Constraint_Error condition 9. copy Temp Reg to Accumator Reg ... As for you code using command line to remove the error checking and using optimization, is kind of cheating. To prove something always set the command line to normaly Ada conditions, based in the RM, not on the whims of the month. Plus, how many new programmers know to use those command options. And some of those people may be using non-GNAT Ada systems. Do not assume that everybody is using GNAT 2007 or 2008 because you might. A lot still use Ada-95 by Janus/IBM/SGI/SUN etc. In <1215965011.20645.42.camel@K72>, Georg Bauhaus <rm.plus-bug.tsoh@maps.futureapps.de> writes: >On Sun, 2008-07-13 at 00:51 +0000, anon wrote: > >> Plus, when a programmer defines their own type in Ada, Ada adds >> extra set of routines that are not based in hardware checks but software, >> which slows a program down. > >I'm not sure there is some real context here. There is no loss >in speed and no cost in terms of additional checks for using >either Unsigned_64 or "mod 2**64". (Or "mod 2**(something smaller)".) >Below is an example to serve as one of many (really unnecessary) >proofs that there is no overhead stemming from user defined types >"mod 2**N". (And no overhead stemming from user defined types >in general---they are there for a reason in this real-time >systems programming language, I should think.) > >Hardware will in the end fetch words from memory etc., but what >does this have to do with using a type mod 2**64 instead >of using Unsigned_64? The compiler produces the code, just the >compiler. Will a 64bit compiler use different intrinsic >routines (such as "+") when the arguments are not Unsigned_64 >but of type mod 2**64? It does *not* seem to be the case, see >below. No magically different checks either. Turning checks >on/off is in the hands of the compiler operator. > >For the code appended, I get not a single difference >in object code when using "mod 2**64" or Unsigned_64. >With or without optimization, neither the representation >nor the instructions differ at all. Not a bit. > >Even using a packed array of 64 Booleans gives the very same >code with -O, and a very small difference results with -O0 >between the boolean array code and the scalar types code. > >I would have expected exactly this to be the case. > >Here is the machine code of subprogram Predefined which >is using Unsigned_64 as an "in out" Parameter, then >followed by machine code of subprogram Programmer_Defined >which uses "mod 2**64". > >First the case with some optimization. >The Ada subprogram is, basically, > >procedure P(Item: in out T) is >begin > Item := not Item; >end P; > >where T stands for Unsigned_64 and "mod 2**64", resp. > >$ gnatmake -gnata -gnato -gnatwa -O -fno-inline speed.adb > >0000000000000000 <speed__predefined.1692>: > 0: 48 89 f8 mov %rdi,%rax > 3: 48 f7 d0 not %rax > 6: c3 retq > 7: 90 nop > >0000000000000008 <speed__programmer_defined.1700>: > 8: 48 89 f8 mov %rdi,%rax > b: 48 f7 d0 not %rax > e: c3 retq > f: 90 nop > >No difference. (And no checks.) > >Next with no optimization at all: > >$ gnatmake -gnata -gnato -gnatwa -O0 -fno-inline speed.adb > >00000000000003c6 <speed__programmer_defined.1700>: > 3c6: 55 push %rbp > 3c7: 48 89 e5 mov %rsp,%rbp > 3ca: 48 89 7d f8 mov %rdi,-0x8(%rbp) > 3ce: 4c 89 55 f0 mov %r10,-0x10(%rbp) > 3d2: 48 f7 55 f8 notq -0x8(%rbp) > 3d6: 48 8b 45 f8 mov -0x8(%rbp),%rax > 3da: c9 leaveq > 3db: c3 retq > >00000000000003dc <speed__predefined.1692>: > 3dc: 55 push %rbp > 3dd: 48 89 e5 mov %rsp,%rbp > 3e0: 48 89 7d f8 mov %rdi,-0x8(%rbp) > 3e4: 4c 89 55 f0 mov %r10,-0x10(%rbp) > 3e8: 48 f7 55 f8 notq -0x8(%rbp) > 3ec: 48 8b 45 f8 mov -0x8(%rbp),%rax > 3f0: c9 leaveq > 3f1: c3 retq > >No difference. (And no checks.) > >with Interfaces; use Interfaces; >with Ada.Text_IO; use Ada.Text_IO; > >procedure Speed2 is > > -- > -- Case 1: > -- reusing predefined type from Interfaces: > -- > > procedure Predefined(Item: in out Unsigned_64) is > begin > Item := not Item; > end Predefined; > > -- > -- Case 2: > -- using a programmer defind modular type: > -- > > type B_Set is mod 2**64; > > procedure Programmer_Defined(Item: in out B_Set) is > begin > Item := not Item; > end Programmer_Defined; > > -- > -- Case 3: > -- using a different programmer defined type: > -- > > type Bit_List is array(Positive range <>) of Boolean; > pragma Pack(Bit_List); > > subtype B_List is Bit_List(1 .. 64); > > > procedure Really_Programmer_Defined(Item: in out B_List) is > begin > Item := not Item; > end Really_Programmer_Defined; > > > -- > -- IO of inputs and results > -- > > package IO_U64 is new Ada.Text_IO.Modular_IO(Unsigned_64); > package IO_B is new Ada.Text_IO.Modular_IO(B_Set); > package IO_L is > > -- a fake IO package for hex output of boolean array `B_List` > > Default_Width : Ada.Text_IO.Field := Unsigned_64'Width; > Default_Base : Ada.Text_IO.Number_Base := 10; > > procedure Put(Item: B_List; > Base: Number_Base := Default_Base; > Width: Field := Default_Width); > end IO_L; > package body IO_L is separate; > >begin -- Speed > > -- Starting with case 3. The bit values are set for position > -- numbered ranges. These will become bit positions in the other > -- cases. > > -- pragma Volatile appears to help prevent Constraint_Error for > -- non-static universal integer in `Value = 16#...#` with current > -- GNAT. > > -- case 3: > > Packed_Arrays: declare > Value: B_List; > begin > Value := B_List' > (1 .. 10 => True, > 11 .. 27 => False, > 28 .. 40 => True, > 41 .. 42 => False, > 43 .. 63 => True, > 64 => False); > Put(" As B_List: "); IO_L.Put(Value, Base => 16); New_Line; > Really_Programmer_Defined(Value); > Put(" As B_List: "); IO_L.Put(Value, Base => 16); New_Line; > end Packed_Arrays; > > > -- case 2: > > User_Mod_Types: declare > Value: B_Set; > pragma Volatile(Value); > begin > Value := >2#1111111111_00000000000000000_1111111111111_00_111111111111111111111_0#; > pragma Assert(Value = 16#FFC0001FFF3FFFFE#); > Put(" As B_Set: "); IO_B.Put(Value, Base => 16); New_Line; > Programmer_Defined(Value); > Put(" As B_Set: "); IO_B.Put(Value, Base => 16); New_Line; > end User_Mod_Types; > > > -- case 1: > > Interface_Types: declare > Value: Unsigned_64; > pragma Volatile(Value); > begin > Value := >2#1111111111_00000000000000000_1111111111111_00_111111111111111111111_0#; > pragma Assert(Value = 16#FFC0001FFF3FFFFE#); > Put("As Unsigned_64: "); IO_U64.Put(Value, Base => 16); New_Line; > Predefined(Value); > Put("As Unsigned_64: "); IO_U64.Put(Value, Base => 16); New_Line; > end Interface_Types; > > >end Speed2; > >separate(Speed2) >package body IO_L is > > > Four : constant Positive := 4; > subtype B_List4 is Bit_List(1 .. Four); > > > function To_Char(Item: B_List4) return Character is > -- Character representing the `Item` as a hex digit > > type N8 is range 0 .. 2**Four - 1; > > function As_N8(Omit_First: Boolean) return N8 is > -- compute `Item`'s value from bits [1,]2,3,4 independent of > -- bit order > Result: N8; > First_Bit: constant Positive := 1 + Boolean'Pos(Omit_First); > begin > Result := 0; > for K in First_Bit .. Four loop > Result := Result + 2**(Four - K) * Boolean'Pos(Item(K)); > end loop; > return Result; > end As_N8; > > begin -- To_Char > if Item(1) and then (Item(2) or Item(3)) then > -- hex digit A, B, ... > return Character'Val(Character'Pos('A') + > As_N8(Omit_First => True) - 2); > else > -- decimal digit > return Character'Val(Character'Pos('0') + > As_N8(Omit_First => False)); > end if; > end To_Char; > > > > procedure Put(Item: B_List; > Base: Number_Base := Default_Base; > Width: Field := Default_Width) > is > Num_Half_Bytes : constant Positive := B_List'Size / Four; > Result: String(1 .. Num_Half_Bytes); > begin > case Base is > when 16 => > for J in 0 .. Num_Half_Bytes - 1 loop > Result(J + 1) := > To_Char(Item((J) * Four + 1 .. (J + 1) * Four)); > end loop; > declare > Extra_Spaces: constant Natural := > Positive'Max(Width - Num_Half_Bytes - 4, 0); > begin > Ada.Text_IO.Put(String'(1 .. Extra_Spaces => ' ') > &"16#" & Result & "#"); > end; > when others => > -- not supported > raise Program_Error; > end case; > end Put; > >end IO_L; > > > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-14 2:03 ` anon @ 2008-07-14 13:12 ` Georg Bauhaus 2008-07-16 6:16 ` micronian2 0 siblings, 1 reply; 27+ messages in thread From: Georg Bauhaus @ 2008-07-14 13:12 UTC (permalink / raw) anon schrieb: > When the CPU or FFU executes a single arithmetic instruction it uses the > build-in CPU Carry flag to detect a Overflow/Underflow condition for those > types that are define in the Standard/System packages. It turns out that the CPU instructions for "mod 2**64" types are the very same as the CPU instructions for Unsigned_64. Assuming you get an advantage from using hardware overflow flags, they will thus be had for either type. > Which is faster > than a set of routines that the compiler generates for a new user type. Q: What routines does the compiler generate for Unsigned_64 but not for "mod 2**64" and vice versa? A: None. Q: What routines does the compiler generate for mod 2**5? A: None that have a jump to constraint error handlers. (Not surprisingly; and see below.) Some that do fast, efficient, modular operations in hardware. (Not surprisingly; see below.) None that could replaced with predefined ones because there is no predefined type with the same properties as "mod 2**5". Not on earth, at least, as far as I can tell. > Actually, in the case of 2**5 the arithmetic > function is done on the processor 8-bit word and then the result is > compared to see if the result is with the range of 2**5. A lot of > instructions are generated instead of only three for build-in types: What makes you think that 2**5 artithmetic is necessarily expensive? It is modular arithmetic on a power of 2. Ada compilers will in many cases do better than what you have outlined. Code for a "mod 2**5" type: type M5 is mod 2**5; function Double_It(Item: M5) return M5 is begin return item + item; end Double_It; $ gnatmake -gnatwa -gnato -O -fno-inline mod5.adb 0000000000000000 <mod5__double_it.912>: 0: 01 ff add %edi,%edi 2: 89 f8 mov %edi,%eax 4: 83 e0 1f and $0x1f,%eax 7: c3 retq %eax is a 32-bit word, and no 8-bit AL or AH register is mentioned. ADD is safe because %edi is bound to contain values of type "mod 2**5", so small that addition can never set a 32bit CPU's unsigned overflow flag. The rest ist just clearing the sequence of carried bits because this is how "mod 2**5" works in binary hardware. Again -gnato is used for turning checks on, in case you had overlooked this when answering. To repeat, I have _never_ seen different code produced for the same algorithm using either Unsigned_N or mod 2**N. Could you give one actual, compilable example so we could convince ourselves that what you claim can be found to be true, concerning the superiority of Unsigned_N over mod 2+*N? -- Georg Bauhaus Y A Time Drain http://www.9toX.de ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-14 13:12 ` Georg Bauhaus @ 2008-07-16 6:16 ` micronian2 2008-07-16 7:47 ` anon 0 siblings, 1 reply; 27+ messages in thread From: micronian2 @ 2008-07-16 6:16 UTC (permalink / raw) On Jul 14, 6:12 am, Georg Bauhaus <rm.dash-bauh...@futureapps.de> wrote: > anon schrieb: [snip] > Q: What routines does the compiler generate for Unsigned_64 > but not for "mod 2**64" and vice versa? > A: None. > Your "mod 2**64" won't get Shift_Arithmetic_Right, Rotate_Left, and Rotate_Right. After some thought, I realized that you can simulate Rotate_Left/Right with shift operations. For example, Rotate_Left(Value, 3) can be performed by doing: Value := (Value * 2**3) or (Value / 2**29) (note: assuming value is 32-bits) For constant values, the compiled output has a good chance of being the same for either "mod 2**64" and Unsigned_64. But what about cases where the shift offsets are not known at compile time? I wrote two little test programs to see how user defined shift and rotate operations for "mod**64" compared to those that were predefined for Interfaces.Unsigned_64 using GNAT GPL2008. For the shift left/right operations, the output was the pretty much the same. For the rotate left/right, the ones for Unsigned_64 generated less code and did not need as many calls to the run-time system. Of course, this is all just based on one compiler. I don't know what other compilers do. Actually I do recall the old GreenHills AdaMULTI 3.0 compiler implemented the operations as calls to C functions. Anyhow, I think I said enough on this. ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-16 6:16 ` micronian2 @ 2008-07-16 7:47 ` anon 2008-07-17 16:33 ` micronian2 0 siblings, 1 reply; 27+ messages in thread From: anon @ 2008-07-16 7:47 UTC (permalink / raw) In GNAT the types and functions define by packages "Standard.ads" and some others like "Interfaces.ads" are treated as special. Note: In GNAT you will not see a package called "Standard" it is built-into the compiler. To check this package you can use "-gnatS" (version GNAT 2005-8) in a command line. Such as: gnat1 <any ada source file>adb -gnatS >standard.ads As for the "Interfaces" package the compiler uses if possible a machine instruction to preform the function. So, when the compile encounters a call to the function "Rotate_Left" for example on a Intel cpu the compiler will use the Intel processor instruction "rol". To see an example. Create a test program and compile it using either the following commands. Two files are create (*.s, and *.ali). gnat compile <test file name>.adb -S <other options if needed> or gnat1 <test file name>.adb <other options if needed> Note: the output of "GNAT1" when excuted by a command line/batch file is normally a assembly source file for the target cpu with its assoc *.ali file. Then just check the file: <test file name>.s Note: the "*.s" can be compiled and then you can use gnatbind/gnatlink to continue to build the program. In <93bcf03d-dd09-4cdd-b4a7-98bf56284ee3@k37g2000hsf.googlegroups.com>, micronian2@gmail.com writes: >On Jul 14, 6:12=A0am, Georg Bauhaus <rm.dash-bauh...@futureapps.de> >wrote: >> anon schrieb: >[snip] >> Q: What routines does the compiler generate for Unsigned_64 >> =A0 =A0 but not for "mod 2**64" and vice versa? >> A: None. >> > >Your "mod 2**64" won't get Shift_Arithmetic_Right, Rotate_Left, and >Rotate_Right. After some thought, I realized that you can simulate >Rotate_Left/Right with shift operations. For example, >Rotate_Left(Value, 3) can be performed by doing: > > Value :=3D (Value * 2**3) or (Value / 2**29) (note: assuming value is >32-bits) > >For constant values, the compiled output has a good chance of being >the same for either "mod 2**64" and Unsigned_64. But what about cases >where the shift offsets are not known at compile time? I wrote two >little test programs to see how user defined shift and rotate >operations for "mod**64" compared to those that were predefined for >Interfaces.Unsigned_64 using GNAT GPL2008. For the shift left/right >operations, the output was the pretty much the same. For the rotate >left/right, the ones for Unsigned_64 generated less code and did not >need as many calls to the run-time system. Of course, this is all just >based on one compiler. I don't know what other compilers do. Actually >I do recall the old GreenHills AdaMULTI 3.0 compiler implemented the >operations as calls to C functions. > >Anyhow, I think I said enough on this. > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-16 7:47 ` anon @ 2008-07-17 16:33 ` micronian2 0 siblings, 0 replies; 27+ messages in thread From: micronian2 @ 2008-07-17 16:33 UTC (permalink / raw) Yes, I'm aware of the .S output. In my previous post, I was referring to the generated assembly code. Using (Value * 2**X) for shift left and (Value / 2**X) for right shift produced the same output as those predefined for Unsigned_N. --Micronian Coder On Jul 16, 12:47 am, a...@anon.org (anon) wrote: > In GNAT the types and functions define by packages "Standard.ads" and > some others like "Interfaces.ads" are treated as special. > > Note: In GNAT you will not see a package called "Standard" it > is built-into the compiler. To check this package you can use > "-gnatS" (version GNAT 2005-8) in a command line. Such as: > > gnat1 <any ada source file>adb -gnatS >standard.ads > > As for the "Interfaces" package the compiler uses if possible a machine > instruction to preform the function. So, when the compile encounters a > call to the function "Rotate_Left" for example on a Intel cpu the > compiler will use the Intel processor instruction "rol". > > To see an example. Create a test program and compile it using either > the following commands. Two files are create (*.s, and *.ali). > > gnat compile <test file name>.adb -S <other options if needed> > > or > > gnat1 <test file name>.adb <other options if needed> > > Note: the output of "GNAT1" when excuted by a command line/batch file > is normally a assembly source file for the target cpu with its assoc *.ali > file. > > Then just check the file: <test file name>.s > > Note: the "*.s" can be compiled and then you can use gnatbind/gnatlink > to continue to build the program. > > In <93bcf03d-dd09-4cdd-b4a7-98bf56284...@k37g2000hsf.googlegroups.com>, microni...@gmail.com writes: > >On Jul 14, 6:12=A0am, Georg Bauhaus <rm.dash-bauh...@futureapps.de> > >wrote: > >> anon schrieb: > >[snip] > >> Q: What routines does the compiler generate for Unsigned_64 > >> =A0 =A0 but not for "mod 2**64" and vice versa? > >> A: None. > > >Your "mod 2**64" won't get Shift_Arithmetic_Right, Rotate_Left, and > >Rotate_Right. After some thought, I realized that you can simulate > >Rotate_Left/Right with shift operations. For example, > >Rotate_Left(Value, 3) can be performed by doing: > > > Value :=3D (Value * 2**3) or (Value / 2**29) (note: assuming value is > >32-bits) > > >For constant values, the compiled output has a good chance of being > >the same for either "mod 2**64" and Unsigned_64. But what about cases > >where the shift offsets are not known at compile time? I wrote two > >little test programs to see how user defined shift and rotate > >operations for "mod**64" compared to those that were predefined for > >Interfaces.Unsigned_64 using GNAT GPL2008. For the shift left/right > >operations, the output was the pretty much the same. For the rotate > >left/right, the ones for Unsigned_64 generated less code and did not > >need as many calls to the run-time system. Of course, this is all just > >based on one compiler. I don't know what other compilers do. Actually > >I do recall the old GreenHills AdaMULTI 3.0 compiler implemented the > >operations as calls to C functions. > > >Anyhow, I think I said enough on this. > > ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-13 16:03 ` Georg Bauhaus 2008-07-14 2:03 ` anon @ 2008-07-14 16:34 ` micronian2 2008-07-14 17:26 ` Georg Bauhaus 1 sibling, 1 reply; 27+ messages in thread From: micronian2 @ 2008-07-14 16:34 UTC (permalink / raw) Hi, In the context of using types such as Unsigned_N from Interfaces, what if you needed the bit shifting operations? From looking at the RM, they are only available for modular types defined in Interfaces: Ada2005 RM2.5.4(28) The same arithmetic operators are predefined for all signed integer types defined by a signed_integer_type_definition (see 4.5, “Operators and Expression Evaluation”). For modular types, these same operators are predefined, plus bit-wise logical operators (and, or, xor, and not). In addition, for the unsigned types declared in the language- defined package Interfaces (see B.2), functions are defined that provide bit-wise shifting and rotating. Of course, a good compiler would probably translate something like 2**X into a shift which is great. But what about Shift_Arithmetic_Right or Rotate_Left? If I had to define my own, then it probably would not be as efficient as a predefined one from Interfaces. It would have been nice if the Ada standard guaranteed such operations were available for user-defined modular types. --Micronian Coder On Jul 13, 9:03 am, Georg Bauhaus <rm.plus- bug.t...@maps.futureapps.de> wrote: > On Sun, 2008-07-13 at 00:51 +0000, anon wrote: > > Plus, when a programmer defines their own type in Ada, Ada adds > > extra set of routines that are not based in hardware checks but software, > > which slows a program down. > > I'm not sure there is some real context here. There is no loss > in speed and no cost in terms of additional checks for using > either Unsigned_64 or "mod 2**64". (Or "mod 2**(something smaller)".) > Below is an example to serve as one of many (really unnecessary) > proofs that there is no overhead stemming from user defined types > "mod 2**N". (And no overhead stemming from user defined types > in general---they are there for a reason in this real-time > systems programming language, I should think.) > [Example code removed] ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-14 16:34 ` micronian2 @ 2008-07-14 17:26 ` Georg Bauhaus 2008-07-16 6:28 ` micronian2 0 siblings, 1 reply; 27+ messages in thread From: Georg Bauhaus @ 2008-07-14 17:26 UTC (permalink / raw) micronian2@gmail.com schrieb: > In the context of using types such as Unsigned_N from Interfaces, what > if you needed the bit shifting operations? What if... Do you have some convincing examples? A special algorithm is probably not a convincing example, even when admirable, or worth millions, because special algorithms typically require special programming efforts. For features to be of the "general purpose" flavor though, i.e. for them to be provided by the language, there should be a general need, not a nice, special one. -- Georg Bauhaus Y A Time Drain http://www.9toX.de ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: Problem using Ada.Text_IO.Modular_IO 2008-07-14 17:26 ` Georg Bauhaus @ 2008-07-16 6:28 ` micronian2 0 siblings, 0 replies; 27+ messages in thread From: micronian2 @ 2008-07-16 6:28 UTC (permalink / raw) On Jul 14, 10:26 am, Georg Bauhaus <rm.dash-bauh...@futureapps.de> wrote: > microni...@gmail.com schrieb: > > > In the context of using types such as Unsigned_N from Interfaces, what > > if you needed the bit shifting operations? > > What if... Do you have some convincing examples? Good point. After reading this, I realized that I usually needed these type of operations to manipulate packed data when I wrote in a language such as C. With Ada I normally can use rep specs and have the compiler generate the necessary bit shifting operations automatically. In addition, with Ada2005 now requiring support for non-default Bit_Order settings, rep specs are even more portable :). Now if only more Ada compilers were supporting Ada2005. GNAT "seems" like the only one that is continuing to make progress these days :(. > > A special algorithm is probably not a convincing example, > even when admirable, or worth millions, because special > algorithms typically require special programming efforts. > For features to be of the "general purpose" flavor though, > i.e. for them to be provided by the language, there should > be a general need, not a nice, special one. Well, there must have been enough compelling reason/need to include the operations for Unsigned_N types in the first place. --Micronian Coder > > -- > Georg Bauhaus > Y A Time Drain http://www.9toX.de ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2008-07-17 16:33 UTC | newest] Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2008-07-09 16:52 Problem using Ada.Text_IO.Modular_IO jujosei 2008-07-09 19:03 ` Anh Vo 2008-07-09 19:22 ` Adam Beneschan 2008-07-09 21:50 ` Adam Beneschan 2008-07-10 15:00 ` jujosei 2008-07-10 0:48 ` anon 2008-07-10 1:52 ` Adam Beneschan 2008-07-10 7:25 ` anon 2008-07-10 14:59 ` Adam Beneschan 2008-07-11 0:34 ` anon 2008-07-11 9:49 ` Georg Bauhaus 2008-07-11 10:05 ` christoph.grein 2008-07-11 13:21 ` John McCormick 2008-07-11 12:16 ` anon 2008-07-11 13:26 ` petter_fryklund 2008-07-11 21:10 ` anon 2008-07-12 10:06 ` Georg Bauhaus 2008-07-13 0:51 ` anon 2008-07-13 16:03 ` Georg Bauhaus 2008-07-14 2:03 ` anon 2008-07-14 13:12 ` Georg Bauhaus 2008-07-16 6:16 ` micronian2 2008-07-16 7:47 ` anon 2008-07-17 16:33 ` micronian2 2008-07-14 16:34 ` micronian2 2008-07-14 17:26 ` Georg Bauhaus 2008-07-16 6:28 ` micronian2
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox