Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #140005 > unrolled thread
| Started by | Bart <bc@freeuk.com> |
|---|---|
| First post | 2019-01-20 00:03 +0000 |
| Last post | 2019-01-21 00:13 -0600 |
| Articles | 20 on this page of 160 — 17 participants |
Back to article view | Back to comp.lang.c
Compiler tests Bart <bc@freeuk.com> - 2019-01-20 00:03 +0000
Re: Compiler tests Ian Collins <ian-news@hotmail.com> - 2019-01-20 16:52 +1300
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-20 10:27 +0100
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-20 12:37 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-20 13:08 +0000
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-20 15:02 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-20 17:31 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-20 17:08 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-20 21:40 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-20 22:41 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-21 00:39 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-21 00:36 +0000
Re: Compiler tests Ian Collins <ian-news@hotmail.com> - 2019-01-21 16:33 +1300
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-21 11:58 +0000
Re: Compiler tests Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-01-21 04:15 -0800
Re: Compiler tests Ian Collins <ian-news@hotmail.com> - 2019-01-22 07:53 +1300
Re: Compiler tests BGB <cr88192@hotmail.com> - 2019-01-23 01:15 -0600
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-23 12:00 +0000
Re: Compiler tests Ian Collins <ian-news@hotmail.com> - 2019-01-24 08:13 +1300
Re: Compiler tests BGB <cr88192@hotmail.com> - 2019-01-23 13:30 -0600
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-21 08:22 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-21 12:23 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-21 14:42 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-21 14:17 +0000
Re: Compiler tests Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-01-21 12:46 -0800
You guys really, really need to get a room (Was: Compiler tests) gazelle@shell.xmission.com (Kenny McCormack) - 2019-01-24 14:05 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-20 17:27 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-20 17:19 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-21 09:44 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-21 12:49 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-21 15:31 +0100
Re: Compiler tests jacobnavia <jacob@jacob.remcomp.fr> - 2019-01-21 14:38 +0100
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-21 15:15 +0100
Re: Compiler tests jacobnavia <jacob@jacob.remcomp.fr> - 2019-01-21 16:05 +0100
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-21 16:39 +0100
Re: Compiler tests Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-01-21 12:51 -0800
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-22 00:16 +0000
Re: Compiler tests jacobnavia <jacob@jacob.remcomp.fr> - 2019-01-22 08:43 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-22 12:31 +0000
Re: Compiler tests jacobnavia <jacob@jacob.remcomp.fr> - 2019-01-22 17:49 +0100
Re: Compiler tests jacobnavia <jacob@jacob.remcomp.fr> - 2019-01-23 11:04 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-23 11:18 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-21 15:35 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-21 15:49 +0000
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-21 17:42 +0100
Re: Compiler tests BGB <cr88192@hotmail.com> - 2019-01-23 03:18 -0600
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-23 11:11 +0100
Re: Compiler tests BGB <cr88192@hotmail.com> - 2019-01-23 12:18 -0600
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-23 13:56 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-22 10:55 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-22 12:07 +0000
Re: Compiler tests fir <profesor.fir@gmail.com> - 2019-01-22 04:29 -0800
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-22 12:52 +0000
Re: Compiler tests mark.bluemel@gmail.com - 2019-01-22 05:04 -0800
Re: Compiler tests fir <profesor.fir@gmail.com> - 2019-01-22 05:18 -0800
Re: Compiler tests fir <profesor.fir@gmail.com> - 2019-01-22 05:45 -0800
Re: Compiler tests fir <profesor.fir@gmail.com> - 2019-01-22 05:35 -0800
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-22 15:10 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-22 17:30 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-22 23:02 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-22 23:14 +0000
Re: Compiler tests Keith Thompson <kst-u@mib.org> - 2019-01-22 15:45 -0800
Re: Compiler tests Robert Wessel <robertwessel2@yahoo.com> - 2019-01-22 17:57 -0600
Re: Compiler tests Keith Thompson <kst-u@mib.org> - 2019-01-22 16:36 -0800
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-23 01:37 +0000
Re: Compiler tests Keith Thompson <kst-u@mib.org> - 2019-01-22 18:53 -0800
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-23 09:42 +0100
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-23 09:22 +0100
Re: Compiler tests James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-23 08:52 -0500
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-23 15:13 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-23 14:33 +0000
Re: Compiler tests James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-23 07:30 -0800
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-23 16:05 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-23 17:17 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-23 16:29 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-23 22:04 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-23 21:50 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-24 10:45 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-24 11:55 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-24 13:58 +0100
Re: Compiler tests mark.bluemel@gmail.com - 2019-01-24 05:07 -0800
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-24 14:10 +0000
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-24 14:18 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-24 15:51 +0100
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-24 15:44 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-24 17:32 +0000
Re: Compiler tests scott@slp53.sl.home (Scott Lurndal) - 2019-01-24 19:07 +0000
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-24 20:14 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-24 22:24 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-24 22:46 +0000
Re: Compiler tests Ian Collins <ian-news@hotmail.com> - 2019-01-25 12:34 +1300
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 01:01 +0000
Re: Compiler tests Ian Collins <ian-news@hotmail.com> - 2019-01-25 14:15 +1300
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 10:05 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 14:51 +0000
Re: Compiler tests Mateusz Viste <mateusz@wont.tell> - 2019-01-25 09:48 +0000
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-25 10:56 +0100
Re: Compiler tests Mateusz Viste <mateusz@wont.tell> - 2019-01-25 12:08 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 13:28 +0100
Re: Compiler tests Mateusz Viste <mateusz@wont.tell> - 2019-01-25 13:33 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 15:38 +0100
Re: Compiler tests Mateusz Viste <mateusz@wont.tell> - 2019-01-25 15:08 +0000
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 13:53 +0000
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 12:25 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 10:03 +0100
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-25 10:08 +0100
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 11:14 +0100
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-25 12:02 +0100
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 13:37 +0100
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-25 13:58 +0100
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 14:26 +0100
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-25 15:01 +0100
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 15:42 +0100
Re: Compiler tests Keith Thompson <kst-u@mib.org> - 2019-01-25 10:25 -0800
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 14:37 +0000
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-25 16:33 +0100
Re: Compiler tests Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-01-25 07:44 -0800
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-25 17:53 +0100
Re: Compiler tests Keith Thompson <kst-u@mib.org> - 2019-01-25 10:33 -0800
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-25 20:43 +0100
Re: Compiler tests Keith Thompson <kst-u@mib.org> - 2019-01-25 12:17 -0800
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 18:31 +0000
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-25 20:41 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 21:19 +0000
Re: Compiler tests Ian Collins <ian-news@hotmail.com> - 2019-01-26 10:24 +1300
Re: Compiler tests "Pascal J. Bourguignon" <pjb@informatimago.com> - 2019-01-25 22:27 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 22:39 +0000
Re: Compiler tests Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-25 18:46 +0000
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 12:43 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 14:37 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 14:19 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 15:47 +0100
Re: Compiler tests Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-01-25 07:17 -0800
Re: Compiler tests Jorgen Grahn <grahn+nntp@snipabacken.se> - 2019-02-03 07:28 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-02-03 12:35 +0100
Re: Compiler tests Jorgen Grahn <grahn+nntp@snipabacken.se> - 2019-02-03 21:47 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-02-03 22:57 +0100
Re: Compiler tests Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-01-24 06:47 -0800
Re: Compiler tests Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-23 20:22 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-23 22:12 +0100
Re: Compiler tests Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-23 21:54 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-24 11:41 +0100
Re: Compiler tests Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-24 23:17 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 11:11 +0100
Re: Compiler tests Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-25 12:04 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 14:05 +0100
Re: Compiler tests Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-25 18:40 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-25 22:36 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-25 22:15 +0000
Re: Compiler tests scott@slp53.sl.home (Scott Lurndal) - 2019-01-25 14:48 +0000
Re: Compiler tests scott@slp53.sl.home (Scott Lurndal) - 2019-01-25 14:46 +0000
Re: Compiler tests Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-01-25 17:48 +0000
Re: Compiler tests James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-01-23 08:23 -0800
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-23 16:41 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-23 16:18 +0000
Re: Compiler tests David Brown <david.brown@hesbynett.no> - 2019-01-23 17:28 +0100
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-23 20:23 +0000
Re: Compiler tests Robert Wessel <robertwessel2@yahoo.com> - 2019-01-22 17:52 -0600
Re: Compiler tests Bart <bc@freeuk.com> - 2019-01-20 20:17 +0000
Re: Compiler tests BGB <cr88192@hotmail.com> - 2019-01-21 00:13 -0600
Page 8 of 8 — ← Prev page 1 2 3 4 5 6 7 [8]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2019-01-23 21:54 +0000 |
| Message-ID | <87imyfxcnu.fsf@bsb.me.uk> |
| In reply to | #140133 |
David Brown <david.brown@hesbynett.no> writes: > On 23/01/2019 21:22, Ben Bacarisse wrote: >> David Brown <david.brown@hesbynett.no> writes: >> >>> On 23/01/2019 17:05, Bart wrote: >> <snip> >>>> There is a problem with finding a general way of translating named >>>> constants in one language to the equivalent in C, where it is necessary >>>> to choose between #define, or enums or just showing the literal directly. >>> >>> There is only a problem because you make it a problem - and you only do >>> that so that you can claim that C has a problem with constants. >> >> Bart has a point here. C /does/ have a problem with "named >> constants" -- what would be thought of in other languages as names >> denoting values. In C, most names denotes objects. enum members can >> name integer values, but that's about it. > > C certainly could be improved regarding constants (C++ has done > so). That is different from saying it has a problem. I don't want to get into an argument about words like "problem". C has almost no way to name a value, and that appears to be fine for most people so maybe there is no "problem". > There are few > uses of named constants that you can't make work in C reasonably > easily (as long as you are not allergic to #define). #define just won't cut it. It names a code construct not a value and that can lead to all sorts of problems. As C programmers, I think we just forget about the problems. When #define USABLE_BYTES 1024 has to turn into #define USABLE_BYTES (calc_bytes_avalable(fp)) we either accept the multiple calls or switch to a "const variable". It's just the cost of doing business in C, just like the other work-arounds you hint at in your reply. > C++ style const > and constexpr give you more. I am not sure what your point is here. Lots of languages give you more. Some even have a uniform way to name values! C++ is hardly to be held up as one that's fixed all this. >> But Bart has also made a problem for himself because he's translating >> into C, not compiling to C. I think he's often trying to find matching >> constructs rather than simply generating code that has the required >> semantics. > > Agreed. That is a good summary. > >> >>> Floating constants will only be used as floating point numbers. You can >>> translate them to "static const double pie = 1.234;" without trouble. >> >> Not when the value is the result of what C views as a non-constant >> expression. OK, so in that case you can just drop the static, but it's >> not as simple as you suggest in general. > > But he is generating the C code. Surely such expressions should be > calculated by his translator, using the source language's semantics > (which could involve different precisions, rounding, etc.) and then > write the literal value directly to the C code. Maybe that is the > translator/compiler issue you mentioned. In Algol 68 (one of the first languages to get this right) INT x = f(y); calls f at run-time (optimisations aside) and names the resulting value x. You can't take the address of x because it's has no storage (again "as if rules" aside), and you can't alter x because it is not a variable. But the key point is that you can't translate that into C by running f at compile time. > Perhaps he would be better translating to C++. I think more of his > concepts would work there. If he compiled into C it would not matter. You would turn the above into int_type v435 = f(v356); with no need for const (to stop assignments) or register (to prevent address taking) because the source language compiler would be doing those checks. He would not have to match the construct in any way. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-01-24 11:41 +0100 |
| Message-ID | <q2c4p0$6i3$1@dont-email.me> |
| In reply to | #140135 |
On 23/01/2019 22:54, Ben Bacarisse wrote: > David Brown <david.brown@hesbynett.no> writes: > >> On 23/01/2019 21:22, Ben Bacarisse wrote: >>> David Brown <david.brown@hesbynett.no> writes: >>> >>>> On 23/01/2019 17:05, Bart wrote: >>> <snip> >>>>> There is a problem with finding a general way of translating named >>>>> constants in one language to the equivalent in C, where it is necessary >>>>> to choose between #define, or enums or just showing the literal directly. >>>> >>>> There is only a problem because you make it a problem - and you only do >>>> that so that you can claim that C has a problem with constants. >>> >>> Bart has a point here. C /does/ have a problem with "named >>> constants" -- what would be thought of in other languages as names >>> denoting values. In C, most names denotes objects. enum members can >>> name integer values, but that's about it. >> >> C certainly could be improved regarding constants (C++ has done >> so). That is different from saying it has a problem. > > I don't want to get into an argument about words like "problem". C has > almost no way to name a value, and that appears to be fine for most > people so maybe there is no "problem". > Fair enough. >> There are few >> uses of named constants that you can't make work in C reasonably >> easily (as long as you are not allergic to #define). > > #define just won't cut it. It names a code construct not a value and > that can lead to all sorts of problems. As C programmers, I think we > just forget about the problems. When > > #define USABLE_BYTES 1024 > > has to turn into > > #define USABLE_BYTES (calc_bytes_avalable(fp)) > > we either accept the multiple calls or switch to a "const variable". > It's just the cost of doing business in C, just like the other > work-arounds you hint at in your reply. > >> C++ style const >> and constexpr give you more. > > I am not sure what your point is here. Lots of languages give you > more. Some even have a uniform way to name values! C++ is hardly to be > held up as one that's fixed all this. > C++ has its history as an extension to C, and retains C as an almost complete subset. Thus it shows some ideas of what could be done to make constants better in C. It is also an option if you want to program basically in C, but with better constants. Other languages may have better ways of handling named constants, but they are further from C. >>> But Bart has also made a problem for himself because he's translating >>> into C, not compiling to C. I think he's often trying to find matching >>> constructs rather than simply generating code that has the required >>> semantics. >> >> Agreed. That is a good summary. >> >>> >>>> Floating constants will only be used as floating point numbers. You can >>>> translate them to "static const double pie = 1.234;" without trouble. >>> >>> Not when the value is the result of what C views as a non-constant >>> expression. OK, so in that case you can just drop the static, but it's >>> not as simple as you suggest in general. >> >> But he is generating the C code. Surely such expressions should be >> calculated by his translator, using the source language's semantics >> (which could involve different precisions, rounding, etc.) and then >> write the literal value directly to the C code. Maybe that is the >> translator/compiler issue you mentioned. > > In Algol 68 (one of the first languages to get this right) > > INT x = f(y); > > calls f at run-time (optimisations aside) and names the resulting value > x. You can't take the address of x because it's has no storage (again > "as if rules" aside), and you can't alter x because it is not a > variable. > I don't see how that differs from C++ : const int x = f(y); You /can/ take the address of x, but that doesn't matter. If the calculations for f(y) and the use of x are such that storage is not needed, storage will not be used. If storage is needed, it /will/ be used. And in Algol, I assume the same applies. C won't let you do this outside a function, which is a limitation. > But the key point is that you can't translate that into C by running f > at compile time. > >> Perhaps he would be better translating to C++. I think more of his >> concepts would work there. > > If he compiled into C it would not matter. You would turn the above > into > > int_type v435 = f(v356); > > with no need for const (to stop assignments) or register (to prevent > address taking) because the source language compiler would be doing > those checks. He would not have to match the construct in any way. > Agreed.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2019-01-24 23:17 +0000 |
| Message-ID | <871s51y7aq.fsf@bsb.me.uk> |
| In reply to | #140151 |
David Brown <david.brown@hesbynett.no> writes: > On 23/01/2019 22:54, Ben Bacarisse wrote: <snip> >> In Algol 68 (one of the first languages to get this right) >> >> INT x = f(y); >> >> calls f at run-time (optimisations aside) and names the resulting value >> x. You can't take the address of x because it's has no storage (again >> "as if rules" aside), and you can't alter x because it is not a >> variable. > > I don't see how that differs from C++ : > > const int x = f(y); > > You /can/ take the address of x, but that doesn't matter. Hmm... why does it not matter? The point is that the C++ statement says something different to the Algol 68 statement. In the C++ case, x must have an observable representation because x denotes an object not a value. It's just nice to be able to write what one means without being obliged to say more. > If the > calculations for f(y) and the use of x are such that storage is not > needed, storage will not be used. If storage is needed, it /will/ be > used. And in Algol, I assume the same applies. That should not dictate what one expresses in the language. For example, most C implementations don't put const objects into non-modifiable storage. None the less, const has a meaning in C independently of how it may or may not be implemented. > C won't let you do this outside a function, which is a limitation. Yes. C's limited provision for such things was the original point. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-01-25 11:11 +0100 |
| Message-ID | <q2enc0$256$1@dont-email.me> |
| In reply to | #140215 |
On 25/01/2019 00:17, Ben Bacarisse wrote: > David Brown <david.brown@hesbynett.no> writes: > >> On 23/01/2019 22:54, Ben Bacarisse wrote: > <snip> >>> In Algol 68 (one of the first languages to get this right) >>> >>> INT x = f(y); >>> >>> calls f at run-time (optimisations aside) and names the resulting value >>> x. You can't take the address of x because it's has no storage (again >>> "as if rules" aside), and you can't alter x because it is not a >>> variable. >> >> I don't see how that differs from C++ : >> >> const int x = f(y); >> >> You /can/ take the address of x, but that doesn't matter. > > Hmm... why does it not matter? The point is that the C++ statement > says something different to the Algol 68 statement. In the C++ case, x > must have an observable representation because x denotes an object not a > value. It's just nice to be able to write what one means without being > obliged to say more. In what circumstances would you have a named constant value that does not have a representation? Does an Algol "INT" represent an abstract integer type, perhaps with unlimited size, rather than a concrete type? (That would be interesting.) I agree that it is nice to be able to write what you mean - no more and no less. But it is rarely possible in programming to get exactly that. Sometimes it is good to have restrictions on how we can use things (objects, functions, whatever) in code. Declaring objects "const" can make it easier to be sure code is correct, help detect mistakes, and possibly improve optimisation. So adding an explicit restriction helps. But I simply don't see any major benefit in a "no address" restriction. I see plenty of efficiency benefit in the compiler being able to avoid making an object in memory if it does not need to - but that is an implementation issue. How often have you seen the storage class "register" used in C (or C++) programming as a way of saying "don't allow the address of this to be taken", rather than as an optimiser hint for old compilers? I would estimate that if you surveyed all the regulars in this group and added them together, you still would not need two hands to count the cases. It just isn't something people find relevant, AFAICS. > >> If the >> calculations for f(y) and the use of x are such that storage is not >> needed, storage will not be used. If storage is needed, it /will/ be >> used. And in Algol, I assume the same applies. > > That should not dictate what one expresses in the language. For > example, most C implementations don't put const objects into > non-modifiable storage. None the less, const has a meaning in C > independently of how it may or may not be implemented. > Certainly "const" is about expressing intention and desired restrictions on access, rather than a concrete demand about object placement. (Though many implementations /do/ put it in non-modifiable storage, or memory segments that are made read-only after loading.) >> C won't let you do this outside a function, which is a limitation. > > Yes. C's limited provision for such things was the original point. > And I agree that this is an unfortunate limitation of C. It does not stop you being able to do most of what you might want with constant data in C, but it certainly could be neater and more flexible.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2019-01-25 12:04 +0000 |
| Message-ID | <87va2dvt86.fsf@bsb.me.uk> |
| In reply to | #140228 |
David Brown <david.brown@hesbynett.no> writes:
> On 25/01/2019 00:17, Ben Bacarisse wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>
>>> On 23/01/2019 22:54, Ben Bacarisse wrote:
>> <snip>
>>>> In Algol 68 (one of the first languages to get this right)
>>>>
>>>> INT x = f(y);
>>>>
>>>> calls f at run-time (optimisations aside) and names the resulting value
>>>> x. You can't take the address of x because it's has no storage (again
>>>> "as if rules" aside), and you can't alter x because it is not a
>>>> variable.
>>>
>>> I don't see how that differs from C++ :
>>>
>>> const int x = f(y);
>>>
>>> You /can/ take the address of x, but that doesn't matter.
>>
>> Hmm... why does it not matter? The point is that the C++ statement
>> says something different to the Algol 68 statement. In the C++ case, x
>> must have an observable representation because x denotes an object not a
>> value. It's just nice to be able to write what one means without being
>> obliged to say more.
>
> In what circumstances would you have a named constant value that does
> not have a representation? Does an Algol "INT" represent an abstract
> integer type, perhaps with unlimited size, rather than a concrete type?
> (That would be interesting.)
Generalising rather too much, a type, concrete or not, will usually
specify a set of values. There is no need for a representation, in the
way the term is used in C, even when the range of values is limited.
I am not sure what you mean with the concrete/abstract distinction here.
The range of INT values in Algol 68 will usually be chosen so that they
can be efficiently represented on the hardware that is being targeted.
> I agree that it is nice to be able to write what you mean - no more and
> no less. But it is rarely possible in programming to get exactly
> that.
Sure. Never exactly that. But C is particularly limited in this
regard. (That's not surprising and I am not "having a go" at C.)
C is an old, low-level language, designed for a very specific purpose.
We know that DMR was much influenced by Algol 68, but I am sure he was
as influenced by the fact that Algol 68 was proving to a challenge to
implement, even on the big machines of the day, as he was by any of the
language features.
> Sometimes it is good to have restrictions on how we can use things
> (objects, functions, whatever) in code. Declaring objects "const" can
> make it easier to be sure code is correct, help detect mistakes, and
> possibly improve optimisation. So adding an explicit restriction helps.
>
> But I simply don't see any major benefit in a "no address"
> restriction.
It is clear that most people get by perfectly well using C, regardless
of the restrictions it imposes. I do too. So I suppose they can't be
major restrictions. But naming values (rather than objects) seems like
a very natural thing to me that I can't do in C.
> I see plenty of efficiency benefit in the compiler being able to avoid
> making an object in memory if it does not need to - but that is an
> implementation issue. How often have you seen the storage class
> "register" used in C (or C++) programming as a way of saying "don't
> allow the address of this to be taken", rather than as an optimiser hint
> for old compilers? I would estimate that if you surveyed all the
> regulars in this group and added them together, you still would not need
> two hands to count the cases. It just isn't something people find
> relevant, AFAICS.
Not being able to take the address is not the issue. The issue is
naming a value. Since you can't do that (in any general way) in C I
would not expect the readers of c.l.c to be too worried by it (I'm not),
but how many would say that they write C code with the intent of naming
a value using various means to get round the restriction:
enum { max_types = 1024 };
#define begin_token "begin"
const double pi = 3.1415;
? I would guess most.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-01-25 14:05 +0100 |
| Message-ID | <q2f1jg$reo$1@dont-email.me> |
| In reply to | #140233 |
On 25/01/2019 13:04, Ben Bacarisse wrote:
> David Brown <david.brown@hesbynett.no> writes:
>
>> On 25/01/2019 00:17, Ben Bacarisse wrote:
>>> David Brown <david.brown@hesbynett.no> writes:
>>>
>>>> On 23/01/2019 22:54, Ben Bacarisse wrote:
>>> <snip>
>>>>> In Algol 68 (one of the first languages to get this right)
>>>>>
>>>>> INT x = f(y);
>>>>>
>>>>> calls f at run-time (optimisations aside) and names the resulting value
>>>>> x. You can't take the address of x because it's has no storage (again
>>>>> "as if rules" aside), and you can't alter x because it is not a
>>>>> variable.
>>>>
>>>> I don't see how that differs from C++ :
>>>>
>>>> const int x = f(y);
>>>>
>>>> You /can/ take the address of x, but that doesn't matter.
>>>
>>> Hmm... why does it not matter? The point is that the C++ statement
>>> says something different to the Algol 68 statement. In the C++ case, x
>>> must have an observable representation because x denotes an object not a
>>> value. It's just nice to be able to write what one means without being
>>> obliged to say more.
>>
>> In what circumstances would you have a named constant value that does
>> not have a representation? Does an Algol "INT" represent an abstract
>> integer type, perhaps with unlimited size, rather than a concrete type?
>> (That would be interesting.)
>
> Generalising rather too much, a type, concrete or not, will usually
> specify a set of values. There is no need for a representation, in the
> way the term is used in C, even when the range of values is limited.
>
> I am not sure what you mean with the concrete/abstract distinction here.
> The range of INT values in Algol 68 will usually be chosen so that they
> can be efficiently represented on the hardware that is being targeted.
The terms "abstract" and "concrete" can be used to mean a lot of things.
Here I am thinking of the distinction between an "integer", which is a
mathematical concept, and something like an "int", which is a specific
type in C. It appears you are saying Algol INT is concrete enough to
have a specific range, but abstract enough that there is no specified
representation.
In C, you are often dealing with values - the representation does not
matter. If you write "const int x = 2;", then use it as "int y = x *
x;", then the representation of "x" is irrelevant. "y" is set to the
value of x squared. It would not matter (other than due to restrictions
in the standard) if "x" were represented in BCD, Turing machine tape
units, or whatever. The C compiler can set "y" based on the value it
should have, without concern for the representation.
I am having a lot of difficulty appreciating why you see the Algol
constant as any different, as long as there is a clear mapping between
the values and the representations, and they cover the same ranges. (It
might not be a one-to-one mapping, considering oddities like signed zeros.)
>
>> I agree that it is nice to be able to write what you mean - no more and
>> no less. But it is rarely possible in programming to get exactly
>> that.
>
> Sure. Never exactly that. But C is particularly limited in this
> regard. (That's not surprising and I am not "having a go" at C.)
Agreed. (And nor I am "defending" C.)
>
> C is an old, low-level language, designed for a very specific purpose.
It is an old language, but it is a high-level language, at least as I
view the term. It is defined in terms of an abstract machine, often
discussing object values rather than representations or implementations.
It has the "as if" rule. You don't specify exactly what the code
should do, you describe how the abstract machine could get the results
you want and let the compiler figure out how to achieve that. It is
certainly a very low level high level language, but if I were to
classify it as either high level or low level, I'd say high level. (For
low-level languages, I'd consider assembly, obviously, and also bytecode
like p-code, and PLC languages like Ladder and IL.)
And while it was originally written for a specific purpose, it turned
out (with enhancements) to work well for a surprisingly wide range of uses.
> We know that DMR was much influenced by Algol 68, but I am sure he was
> as influenced by the fact that Algol 68 was proving to a challenge to
> implement, even on the big machines of the day, as he was by any of the
> language features.
>
Yes - C was intended to be easier to implement in a compiler.
>> Sometimes it is good to have restrictions on how we can use things
>> (objects, functions, whatever) in code. Declaring objects "const" can
>> make it easier to be sure code is correct, help detect mistakes, and
>> possibly improve optimisation. So adding an explicit restriction helps.
>>
>> But I simply don't see any major benefit in a "no address"
>> restriction.
>
> It is clear that most people get by perfectly well using C, regardless
> of the restrictions it imposes. I do too. So I suppose they can't be
> major restrictions. But naming values (rather than objects) seems like
> a very natural thing to me that I can't do in C.
>
>> I see plenty of efficiency benefit in the compiler being able to avoid
>> making an object in memory if it does not need to - but that is an
>> implementation issue. How often have you seen the storage class
>> "register" used in C (or C++) programming as a way of saying "don't
>> allow the address of this to be taken", rather than as an optimiser hint
>> for old compilers? I would estimate that if you surveyed all the
>> regulars in this group and added them together, you still would not need
>> two hands to count the cases. It just isn't something people find
>> relevant, AFAICS.
>
> Not being able to take the address is not the issue. The issue is
> naming a value. Since you can't do that (in any general way) in C I
> would not expect the readers of c.l.c to be too worried by it (I'm not),
> but how many would say that they write C code with the intent of naming
> a value using various means to get round the restriction:
>
> enum { max_types = 1024 };
>
> #define begin_token "begin"
>
> const double pi = 3.1415;
>
> ? I would guess most.
>
I'd say these /are/ all ways of naming constants of different types. I
guess you are naming something that has a value, rather than naming the
value. But I'd also say that makes more sense. Surely a thing should
only have one name - if we were to say "max_types is the name of the
value 1024", then we could not then also say "max_objects is the name of
the value 1024". Or am I reading too much into this?
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2019-01-25 18:40 +0000 |
| Message-ID | <87h8dwwph1.fsf@bsb.me.uk> |
| In reply to | #140244 |
David Brown <david.brown@hesbynett.no> writes:
> On 25/01/2019 13:04, Ben Bacarisse wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>
>>> On 25/01/2019 00:17, Ben Bacarisse wrote:
>>>> David Brown <david.brown@hesbynett.no> writes:
>>>>
>>>>> On 23/01/2019 22:54, Ben Bacarisse wrote:
>>>> <snip>
>>>>>> In Algol 68 (one of the first languages to get this right)
>>>>>>
>>>>>> INT x = f(y);
>>>>>>
>>>>>> calls f at run-time (optimisations aside) and names the resulting value
>>>>>> x. You can't take the address of x because it's has no storage (again
>>>>>> "as if rules" aside), and you can't alter x because it is not a
>>>>>> variable.
>>>>>
>>>>> I don't see how that differs from C++ :
>>>>>
>>>>> const int x = f(y);
>>>>>
>>>>> You /can/ take the address of x, but that doesn't matter.
>>>>
>>>> Hmm... why does it not matter? The point is that the C++ statement
>>>> says something different to the Algol 68 statement. In the C++ case, x
>>>> must have an observable representation because x denotes an object not a
>>>> value. It's just nice to be able to write what one means without being
>>>> obliged to say more.
>>>
>>> In what circumstances would you have a named constant value that does
>>> not have a representation? Does an Algol "INT" represent an abstract
>>> integer type, perhaps with unlimited size, rather than a concrete type?
>>> (That would be interesting.)
>>
>> Generalising rather too much, a type, concrete or not, will usually
>> specify a set of values. There is no need for a representation, in the
>> way the term is used in C, even when the range of values is limited.
>>
>> I am not sure what you mean with the concrete/abstract distinction here.
>> The range of INT values in Algol 68 will usually be chosen so that they
>> can be efficiently represented on the hardware that is being targeted.
>
> The terms "abstract" and "concrete" can be used to mean a lot of things.
>
> Here I am thinking of the distinction between an "integer", which is a
> mathematical concept, and something like an "int", which is a specific
> type in C. It appears you are saying Algol INT is concrete enough to
> have a specific range, but abstract enough that there is no specified
> representation.
If you want to put it that way. I'd say it's abstract. The fact that
we might define an "hour" type to be 0..23 does not make it concrete in
my book, but as you know, I'm not a fan of arguing over vague words.
<snip>
> I am having a lot of difficulty appreciating why you see the Algol
> constant as any different, as long as there is a clear mapping between
> the values and the representations, and they cover the same ranges. (It
> might not be a one-to-one mapping, considering oddities like signed
> zeros.)
OK. And I am having trouble appreciating why you don't see naming a
value as different from naming a non-modifiable lvalue. Is there much
point in either of us trying to find out? I suspect is just a different
point of view.
>>> I agree that it is nice to be able to write what you mean - no more and
>>> no less. But it is rarely possible in programming to get exactly
>>> that.
>>
>> Sure. Never exactly that. But C is particularly limited in this
>> regard. (That's not surprising and I am not "having a go" at C.)
>
> Agreed. (And nor I am "defending" C.)
>
>>
>> C is an old, low-level language, designed for a very specific purpose.
>
> It is an old language, but it is a high-level language, at least as I
> view the term. It is defined in terms of an abstract machine, often
> discussing object values rather than representations or
> implementations.
The representation options are explicit and you can test them. You can
examine the representation and play tricks with it, even in portable
code.
> It has the "as if" rule.
Indeed, so even the "representation" may be faked. C has to /appear/ to
use plain binary bits for positive integers, but that does not stop it
being low-level in my book.
> You don't specify exactly what the code
> should do, you describe how the abstract machine could get the results
> you want and let the compiler figure out how to achieve that. It is
> certainly a very low level high level language, but if I were to
> classify it as either high level or low level, I'd say high level. (For
> low-level languages, I'd consider assembly, obviously, and also bytecode
> like p-code, and PLC languages like Ladder and IL.)
I don't know those (the last two). I might take a look because I'd like
to see how low you need to go to be low-level in your book.
<snip>
>> Not being able to take the address is not the issue. The issue is
>> naming a value. Since you can't do that (in any general way) in C I
>> would not expect the readers of c.l.c to be too worried by it (I'm not),
>> but how many would say that they write C code with the intent of naming
>> a value using various means to get round the restriction:
>>
>> enum { max_types = 1024 };
>>
>> #define begin_token "begin"
>>
>> const double pi = 3.1415;
>>
>> ? I would guess most.
>>
>
> I'd say these /are/ all ways of naming constants of different types. I
> guess you are naming something that has a value, rather than naming the
> value. But I'd also say that makes more sense. Surely a thing should
> only have one name - if we were to say "max_types is the name of the
> value 1024", then we could not then also say "max_objects is the name of
> the value 1024". Or am I reading too much into this?
I don't really see what your point is. My point seems (to me) to be so
simple and reasonable that I don't understand your objection. I don't
want to change C, so there is no need to say "C can manage" -- I know it
can, but none the less, there is no uniform way to name a value in C.
Algol 68 makes all this very explicit:
INT x = 42; CO x names a value OC
INT x := 42; CO x names a location that can hold a value OC
The latter is a short-hand for
REF INT x = LOC INT := 42
roughly: LOC INT is a locally allocated (stack) int assigned 42, and the
name x refers to that location.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-01-25 22:36 +0100 |
| Message-ID | <q2fvgd$s7i$1@dont-email.me> |
| In reply to | #140277 |
On 25/01/2019 19:40, Ben Bacarisse wrote:
> David Brown <david.brown@hesbynett.no> writes:
>
>> On 25/01/2019 13:04, Ben Bacarisse wrote:
>>> David Brown <david.brown@hesbynett.no> writes:
>>>
>>>> On 25/01/2019 00:17, Ben Bacarisse wrote:
>>>>> David Brown <david.brown@hesbynett.no> writes:
>>>>>
>>>>>> On 23/01/2019 22:54, Ben Bacarisse wrote:
>>>>> <snip>
>>>>>>> In Algol 68 (one of the first languages to get this right)
>>>>>>>
>>>>>>> INT x = f(y);
>>>>>>>
>>>>>>> calls f at run-time (optimisations aside) and names the resulting value
>>>>>>> x. You can't take the address of x because it's has no storage (again
>>>>>>> "as if rules" aside), and you can't alter x because it is not a
>>>>>>> variable.
>>>>>>
>>>>>> I don't see how that differs from C++ :
>>>>>>
>>>>>> const int x = f(y);
>>>>>>
>>>>>> You /can/ take the address of x, but that doesn't matter.
>>>>>
>>>>> Hmm... why does it not matter? The point is that the C++ statement
>>>>> says something different to the Algol 68 statement. In the C++ case, x
>>>>> must have an observable representation because x denotes an object not a
>>>>> value. It's just nice to be able to write what one means without being
>>>>> obliged to say more.
>>>>
>>>> In what circumstances would you have a named constant value that does
>>>> not have a representation? Does an Algol "INT" represent an abstract
>>>> integer type, perhaps with unlimited size, rather than a concrete type?
>>>> (That would be interesting.)
>>>
>>> Generalising rather too much, a type, concrete or not, will usually
>>> specify a set of values. There is no need for a representation, in the
>>> way the term is used in C, even when the range of values is limited.
>>>
>>> I am not sure what you mean with the concrete/abstract distinction here.
>>> The range of INT values in Algol 68 will usually be chosen so that they
>>> can be efficiently represented on the hardware that is being targeted.
>>
>> The terms "abstract" and "concrete" can be used to mean a lot of things.
>>
>> Here I am thinking of the distinction between an "integer", which is a
>> mathematical concept, and something like an "int", which is a specific
>> type in C. It appears you are saying Algol INT is concrete enough to
>> have a specific range, but abstract enough that there is no specified
>> representation.
>
> If you want to put it that way. I'd say it's abstract. The fact that
> we might define an "hour" type to be 0..23 does not make it concrete in
> my book, but as you know, I'm not a fan of arguing over vague words.
>
Agreed. These words are relative, not absolute. If we spent enough
time discussing exactly how we each define them, and how we happen to be
using them in this case, we'd probably agree - but it is not worth the
time and effort.
> <snip>
>> I am having a lot of difficulty appreciating why you see the Algol
>> constant as any different, as long as there is a clear mapping between
>> the values and the representations, and they cover the same ranges. (It
>> might not be a one-to-one mapping, considering oddities like signed
>> zeros.)
>
> OK. And I am having trouble appreciating why you don't see naming a
> value as different from naming a non-modifiable lvalue. Is there much
> point in either of us trying to find out? I suspect is just a different
> point of view.
>
I think you may be right. I'd been hoping I'd suddenly understand what
you are getting at (whether I agree with it or not), but that does not
seem to have happened. We can try again another time in another context.
>>>> I agree that it is nice to be able to write what you mean - no more and
>>>> no less. But it is rarely possible in programming to get exactly
>>>> that.
>>>
>>> Sure. Never exactly that. But C is particularly limited in this
>>> regard. (That's not surprising and I am not "having a go" at C.)
>>
>> Agreed. (And nor I am "defending" C.)
>>
>>>
>>> C is an old, low-level language, designed for a very specific purpose.
>>
>> It is an old language, but it is a high-level language, at least as I
>> view the term. It is defined in terms of an abstract machine, often
>> discussing object values rather than representations or
>> implementations.
>
> The representation options are explicit and you can test them. You can
> examine the representation and play tricks with it, even in portable
> code.
True. (My work relies on that, though it rarely has to be very portable.)
>
>> It has the "as if" rule.
>
> Indeed, so even the "representation" may be faked. C has to /appear/ to
> use plain binary bits for positive integers, but that does not stop it
> being low-level in my book.
>
We are just back to a choice of definitions, and where we draw the lines.
>> You don't specify exactly what the code
>> should do, you describe how the abstract machine could get the results
>> you want and let the compiler figure out how to achieve that. It is
>> certainly a very low level high level language, but if I were to
>> classify it as either high level or low level, I'd say high level. (For
>> low-level languages, I'd consider assembly, obviously, and also bytecode
>> like p-code, and PLC languages like Ladder and IL.)
>
> I don't know those (the last two). I might take a look because I'd like
> to see how low you need to go to be low-level in your book.
>
Programmable Logic Controllers were invented as a software programmable
alternative to automation engineer's racks of timers, relays, and
switches - the sort of system used to control machinery, factories, etc.
The "ladder" programming language is a direct representation of that -
you write your program graphically, connecting up elements that are
effectively relays, inputs, outputs, timers, etc. Two relays connected
in series makes an "AND" gate, two relays in parallel makes an "OR"
gate. That kind of thing. When run, the program starts at the top and
works through the network, following each open path and stopping at each
closed path. Once it reaches the bottom, it starts at the top again (a
new "scan"). For older PLCs, the cpu's instruction set was directly
related to these elements, and Ladder is not far above a graphical
picture of assembly language. Modern PLCs use standard cpus (as they
are cheaper than specialist ones, and it's easier to add features like
Ethernet networking modules) - they may even run a general purpose OS
underneath. The Ladder implementation can be compiled very directly to
assembly, or interpreted.
IL, "instruction list", is very roughly a textual equivalent of Ladder.
> <snip>
>>> Not being able to take the address is not the issue. The issue is
>>> naming a value. Since you can't do that (in any general way) in C I
>>> would not expect the readers of c.l.c to be too worried by it (I'm not),
>>> but how many would say that they write C code with the intent of naming
>>> a value using various means to get round the restriction:
>>>
>>> enum { max_types = 1024 };
>>>
>>> #define begin_token "begin"
>>>
>>> const double pi = 3.1415;
>>>
>>> ? I would guess most.
>>>
>>
>> I'd say these /are/ all ways of naming constants of different types. I
>> guess you are naming something that has a value, rather than naming the
>> value. But I'd also say that makes more sense. Surely a thing should
>> only have one name - if we were to say "max_types is the name of the
>> value 1024", then we could not then also say "max_objects is the name of
>> the value 1024". Or am I reading too much into this?
>
> I don't really see what your point is. My point seems (to me) to be so
> simple and reasonable that I don't understand your objection. I don't
> want to change C, so there is no need to say "C can manage" -- I know it
> can, but none the less, there is no uniform way to name a value in C.
>
> Algol 68 makes all this very explicit:
>
> INT x = 42; CO x names a value OC
> INT x := 42; CO x names a location that can hold a value OC
>
> The latter is a short-hand for
>
> REF INT x = LOC INT := 42
>
> roughly: LOC INT is a locally allocated (stack) int assigned 42, and the
> name x refers to that location.
>
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2019-01-25 22:15 +0000 |
| Message-ID | <DUL2E.139418$DF1.69509@fx34.am4> |
| In reply to | #140277 |
On 25/01/2019 18:40, Ben Bacarisse wrote:
> David Brown <david.brown@hesbynett.no> writes:
>
>> On 25/01/2019 13:04, Ben Bacarisse wrote:
>>> David Brown <david.brown@hesbynett.no> writes:
>>>
>>>> On 25/01/2019 00:17, Ben Bacarisse wrote:
>>>>> David Brown <david.brown@hesbynett.no> writes:
>>>>>
>>>>>> On 23/01/2019 22:54, Ben Bacarisse wrote:
>>>>> <snip>
>>>>>>> In Algol 68 (one of the first languages to get this right)
>>>>>>>
>>>>>>> INT x = f(y);
>>>>>>>
>>>>>>> calls f at run-time (optimisations aside) and names the resulting value
>>>>>>> x. You can't take the address of x because it's has no storage (again
>>>>>>> "as if rules" aside), and you can't alter x because it is not a
>>>>>>> variable.
>>>>>>
>>>>>> I don't see how that differs from C++ :
>>>>>>
>>>>>> const int x = f(y);
>>>>>>
>>>>>> You /can/ take the address of x, but that doesn't matter.
>>>>>
>>>>> Hmm... why does it not matter? The point is that the C++ statement
>>>>> says something different to the Algol 68 statement. In the C++ case, x
>>>>> must have an observable representation because x denotes an object not a
>>>>> value. It's just nice to be able to write what one means without being
>>>>> obliged to say more.
>>>>
>>>> In what circumstances would you have a named constant value that does
>>>> not have a representation? Does an Algol "INT" represent an abstract
>>>> integer type, perhaps with unlimited size, rather than a concrete type?
>>>> (That would be interesting.)
>>>
>>> Generalising rather too much, a type, concrete or not, will usually
>>> specify a set of values. There is no need for a representation, in the
>>> way the term is used in C, even when the range of values is limited.
>>>
>>> I am not sure what you mean with the concrete/abstract distinction here.
>>> The range of INT values in Algol 68 will usually be chosen so that they
>>> can be efficiently represented on the hardware that is being targeted.
>>
>> The terms "abstract" and "concrete" can be used to mean a lot of things.
>>
>> Here I am thinking of the distinction between an "integer", which is a
>> mathematical concept, and something like an "int", which is a specific
>> type in C. It appears you are saying Algol INT is concrete enough to
>> have a specific range, but abstract enough that there is no specified
>> representation.
>
> If you want to put it that way. I'd say it's abstract. The fact that
> we might define an "hour" type to be 0..23 does not make it concrete in
> my book, but as you know, I'm not a fan of arguing over vague words.
>
> <snip>
>> I am having a lot of difficulty appreciating why you see the Algol
>> constant as any different, as long as there is a clear mapping between
>> the values and the representations, and they cover the same ranges. (It
>> might not be a one-to-one mapping, considering oddities like signed
>> zeros.)
>
> OK. And I am having trouble appreciating why you don't see naming a
> value as different from naming a non-modifiable lvalue. Is there much
> point in either of us trying to find out? I suspect is just a different
> point of view.
>
>>>> I agree that it is nice to be able to write what you mean - no more and
>>>> no less. But it is rarely possible in programming to get exactly
>>>> that.
>>>
>>> Sure. Never exactly that. But C is particularly limited in this
>>> regard. (That's not surprising and I am not "having a go" at C.)
>>
>> Agreed. (And nor I am "defending" C.)
>>
>>>
>>> C is an old, low-level language, designed for a very specific purpose.
>>
>> It is an old language, but it is a high-level language, at least as I
>> view the term. It is defined in terms of an abstract machine, often
>> discussing object values rather than representations or
>> implementations.
>
> The representation options are explicit and you can test them. You can
> examine the representation and play tricks with it, even in portable
> code.
>
>> It has the "as if" rule.
>
> Indeed, so even the "representation" may be faked. C has to /appear/ to
> use plain binary bits for positive integers, but that does not stop it
> being low-level in my book.
>
>> You don't specify exactly what the code
>> should do, you describe how the abstract machine could get the results
>> you want and let the compiler figure out how to achieve that. It is
>> certainly a very low level high level language, but if I were to
>> classify it as either high level or low level, I'd say high level. (For
>> low-level languages, I'd consider assembly, obviously, and also bytecode
>> like p-code, and PLC languages like Ladder and IL.)
>
> I don't know those (the last two). I might take a look because I'd like
> to see how low you need to go to be low-level in your book.
>
> <snip>
>>> Not being able to take the address is not the issue. The issue is
>>> naming a value. Since you can't do that (in any general way) in C I
>>> would not expect the readers of c.l.c to be too worried by it (I'm not),
>>> but how many would say that they write C code with the intent of naming
>>> a value using various means to get round the restriction:
>>>
>>> enum { max_types = 1024 };
>>>
>>> #define begin_token "begin"
>>>
>>> const double pi = 3.1415;
>>>
>>> ? I would guess most.
>>>
>>
>> I'd say these /are/ all ways of naming constants of different types. I
>> guess you are naming something that has a value, rather than naming the
>> value. But I'd also say that makes more sense. Surely a thing should
>> only have one name - if we were to say "max_types is the name of the
>> value 1024", then we could not then also say "max_objects is the name of
>> the value 1024". Or am I reading too much into this?
>
> I don't really see what your point is. My point seems (to me) to be so
> simple and reasonable that I don't understand your objection. I don't
> want to change C, so there is no need to say "C can manage" -- I know it
> can, but none the less, there is no uniform way to name a value in C.
>
> Algol 68 makes all this very explicit:
>
> INT x = 42; CO x names a value OC
> INT x := 42; CO x names a location that can hold a value OC
>
> The latter is a short-hand for
>
> REF INT x = LOC INT := 42
>
> roughly: LOC INT is a locally allocated (stack) int assigned 42, and the
> name x refers to that location.
An assembler makes it explicit too. At least, a simple one like mine
(people do like to make assemblers much more complex than need be).
Your example would be:
x = 42 # (or 'equ' in some) name a value as "x"
y: # label this location with "y"
dw 42 # initialise next 4 bytes with 42
...
mov a0, x # immediate load of 42
mov a1, [y] # indirect load from location y, of 42
The 'const' feature in my language (not C's) directly correlates to the
x above:
const x = 42
int32 y = 42 # "=" makes y static if inside a function
Actually, 'const' was mainly intended to name values that otherwise
appear as literal values, mainly integers and floats.
In C, there is no one way of defining that x, although this is the
closest (but limited to an int type):
enum {x = 42};
int32_t y=42;
While doing this in C:
const int x = 42;
is the equivalent, in assembly, of:
segment rodata # optional
x:
dw 42 # when x is static
When x is a local non-static, then it could be anything, eg:
mov dw [ebp+x], 42 # x itself is some offset
But it /could/ also be compiled as this:
x = 42
if the compiler can figure out that it can be.
That's why all this business in C is messy, vague, and unpredictable.
And why you are allowed to to do &x.
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2019-01-25 14:48 +0000 |
| Message-ID | <clF2E.175952$Q95.93114@fx41.iad> |
| In reply to | #140228 |
David Brown <david.brown@hesbynett.no> writes: >On 25/01/2019 00:17, Ben Bacarisse wrote: >> David Brown <david.brown@hesbynett.no> writes: >> >>> On 23/01/2019 22:54, Ben Bacarisse wrote: >> <snip> >>>> In Algol 68 (one of the first languages to get this right) >>>> >>>> INT x = f(y); >>>> >>>> calls f at run-time (optimisations aside) and names the resulting value >>>> x. You can't take the address of x because it's has no storage (again >>>> "as if rules" aside), and you can't alter x because it is not a >>>> variable. >>> >>> I don't see how that differs from C++ : >>> >>> const int x = f(y); >>> >>> You /can/ take the address of x, but that doesn't matter. >> >> Hmm... why does it not matter? The point is that the C++ statement >> says something different to the Algol 68 statement. In the C++ case, x >> must have an observable representation because x denotes an object not a >> value. It's just nice to be able to write what one means without being >> obliged to say more. > >In what circumstances would you have a named constant value that does >not have a representation? Does an Algol "INT" represent an abstract >integer type, perhaps with unlimited size, rather than a concrete type? > (That would be interesting.) In the two Algol implementations I'm familiar with, space would have been allocated for 'x' (because neither machine had registers as we know them today - both Burroughs machines). And real code was written in 'supersets' of Algol-68 (DCAlgol and the OS implementation language, NEWP).
[toc] | [prev] | [next] | [standalone]
| From | scott@slp53.sl.home (Scott Lurndal) |
|---|---|
| Date | 2019-01-25 14:46 +0000 |
| Message-ID | <NiF2E.175866$Q95.32980@fx41.iad> |
| In reply to | #140215 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes: >David Brown <david.brown@hesbynett.no> writes: > >> On 23/01/2019 22:54, Ben Bacarisse wrote: ><snip> >>> In Algol 68 (one of the first languages to get this right) >>> >>> INT x = f(y); >>> >>> calls f at run-time (optimisations aside) and names the resulting value >>> x. You can't take the address of x because it's has no storage (again >>> "as if rules" aside), and you can't alter x because it is not a >>> variable. >> >> I don't see how that differs from C++ : >> >> const int x = f(y); >> >> You /can/ take the address of x, but that doesn't matter. Or in early C, you could write 'register int x = f(y)' and the compiler would forbid you from taking the address of x.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2019-01-25 17:48 +0000 |
| Message-ID | <87munowrv1.fsf@bsb.me.uk> |
| In reply to | #140255 |
scott@slp53.sl.home (Scott Lurndal) writes:
> Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
>>David Brown <david.brown@hesbynett.no> writes:
>>
>>> On 23/01/2019 22:54, Ben Bacarisse wrote:
>><snip>
>>>> In Algol 68 (one of the first languages to get this right)
>>>>
>>>> INT x = f(y);
>>>>
>>>> calls f at run-time (optimisations aside) and names the resulting value
>>>> x. You can't take the address of x because it's has no storage (again
>>>> "as if rules" aside), and you can't alter x because it is not a
>>>> variable.
>>>
>>> I don't see how that differs from C++ :
>>>
>>> const int x = f(y);
>>>
>>> You /can/ take the address of x, but that doesn't matter.
>
> Or in early C, you could write 'register int x = f(y)' and
> the compiler would forbid you from taking the address of x.
Yes (I mentioned that as one option somewhere else) and it's true even
today:
6.5.3.2 Address and indirection operators
Constraints
1 The operand of the unary & operator shall be either a function
designator, the result of a [] or unary * operator, or an lvalue
that designates an object that is not a bit-field and is not
declared with the register storage-class specifier.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2019-01-23 08:23 -0800 |
| Message-ID | <c66f2862-03ef-41e5-bec9-137a32d4a630@googlegroups.com> |
| In reply to | #140121 |
On Wednesday, January 23, 2019 at 11:05:34 AM UTC-5, Bart wrote:
> On 23/01/2019 15:30, James Kuyper wrote:
> > On Wednesday, January 23, 2019 at 9:33:38 AM UTC-5, Bart wrote:
...
> >> If I were to do:
> >> const s = "abc"
> >> print s,s,s
> >>
> >> then "abc" is effectively repeated 3 times. (The C translation has three
> >> lots of "abc" in the source)
> >
> > So he's right - it is a limitation in your own language for how
> > you handle strings. That's a poor translation. Given your general
> > confusion about arrays and pointers, I'm not sure whether tha
> > declaration in your language should be translated to C as
> > const char *s = "abc";
> >
> > or as
> >
> > const char s[] = "abc";
>
> Neither applies; see below.
>
> > but either way, the print statement should be translated to C
> > using something like the following:
> >
> > printf("%s%s%s", s, s, s);
> >
>
> There is a problem with finding a general way of translating named
> constants in one language to the equivalent in C, where it is necessary
> to choose between #define, or enums or just showing the literal directly.
>
> So the decision is made to just show literals which works for all types
> that can follow 'const':
>
> const pie = 2.71828
> print pie,pie,pie # ('pi' is a built-in constant)
>
> The generated C is ('print' adds item spacing):
>
> printf("%f %f %f",(double)2.718280,(double)2.718280,
> (double)2.718280);
Why cast them to double? Those constants already have the type "double".
> The same logic applies to string constants. The idea of named constants
> is that the effect should be the same as if you had just typed the
> constant itself.
In C it makes more sense to use address constants rather than
string constants. That's precisely the role that s serves in the
code I wrote above, if s id declared static. If you're using an implementation that merges identical string literals, using "abc"
directly will also have the same effect - but otherwise it wastes
space.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-01-23 16:41 +0100 |
| Message-ID | <q2a204$se9$1@dont-email.me> |
| In reply to | #140118 |
On 23/01/2019 15:33, Bart wrote:
> On 23/01/2019 08:22, David Brown wrote:
>> On 23/01/2019 00:14, Bart wrote:
>
> [Embedding files as data]
>
>>> In the compiled language, this only works for text files (as strings
>>> can't have embedded zeros), but it ought to work with html:
>>
>> Strings, including string literals, can have embedded zeros. But for
>> binary files, the addition of the terminating 0 at the end of the string
>> may be an issue.
>
> There are all sorts of problems with binary data, so that I only allow
> text. There were also problems in the script language, but there I made
> it work; the use of counted string types made it easier.
Text files might be easier, but that is very little use if you need
binary files.
>
> If I try this:
>
> ichar words=strinclude "hello.exe"
>
> (where hello.exe is a 2.5K file), and translate to C, I get:
>
> static byte * t_words = (byte*)"MZ";
>
> A three-character string (the third char with code 0x90 is not shown
> here). Even if the translation includes all 2560 bytes using \xx codes
> within the string, there still isn't a mechanism to to denote the length.
You are in control of the language and the code generator. Why not make
it simple:
ichar words = bininclude "hello.exe"
Translate to C:
enum { words_length = 2560 };
const uint8_t words[words_length] = {
0x4c, 0x5a, 0x90, 0x00, ...
};
You could also leave the array length unspecified, and use sizeof to
read it, but that would not be exported (if you need the array to be
visible from other modules).
>
>>> (Here it's important not to use 'const index_html = ...' otherwise the
>>> string constant is duplicated for each use. When translating to C, some
>>> compilers already balk at long string constants.))
>>
>> That makes no sense whatsoever. Or are you talking about a limitation
>> in your own language for how you handle strings? "const" does not make
>> things duplicated in C.
>
> If I were to do:
> const s = "abc"
> print s,s,s
>
> then "abc" is effectively repeated 3 times. (The C translation has three
> lots of "abc" in the source)
That is a clear limitation with your code generator (or your language -
you decide).
However, there is an easy solution. Use gcc. Identical string literals
in the same file will be merged. The "-fmerge-constants" flag (enabled
with optimisation -O1 and above) will merge the strings across
compilation units. "-fmerge-all-constants", which must be given
explicitly (since it is non-conforming) will do so even for initialised
const arrays.
>
> With very long strings, you don't really want them duplicated as it can
> increase the executable size significantly. (Maybe some C compilers will
> detect identical string constants and only have one instance, but I
> haven't looked into it.)
>
I agree - and so do the gcc developers.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2019-01-23 16:18 +0000 |
| Message-ID | <et02E.77225$XD2.7320@fx10.am4> |
| In reply to | #140120 |
On 23/01/2019 15:41, David Brown wrote:
> On 23/01/2019 15:33, Bart wrote:
>> If I try this:
>>
>> ichar words=strinclude "hello.exe"
>>
>> (where hello.exe is a 2.5K file), and translate to C, I get:
>>
>> static byte * t_words = (byte*)"MZ";
>>
>> A three-character string (the third char with code 0x90 is not shown
>> here). Even if the translation includes all 2560 bytes using \xx codes
>> within the string, there still isn't a mechanism to to denote the length.
>
> You are in control of the language and the code generator. Why not make
> it simple:
>
> ichar words = bininclude "hello.exe"
>
> Translate to C:
>
> enum { words_length = 2560 };
> const uint8_t words[words_length] = {
> 0x4c, 0x5a, 0x90, 0x00, ...
> };
Because it's a bit harder!
('strinclude' is a lexical directive that yields one token - a string
constant, of type pointer to char; much simpler. That's not to say I
can't do that, but it hasn't come up yet. It would done like this:
[]byte imfiledata = bininclude "fred.jpg"
Once that is done, then the translation to C needs nothing special
(except that it would generate a {...} data sequence with one byte per
line, spanning possibly millions of lines).
There would also be an overhead of 64 memory bytes per data byte, in the
compiler, putting an upper limit on the file sizes, unless I invent some
special handling. The strinclude version only uses one memory byte per
data byte.)
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2019-01-23 17:28 +0100 |
| Message-ID | <q2a4nj$eov$1@dont-email.me> |
| In reply to | #140123 |
On 23/01/2019 17:18, Bart wrote:
> On 23/01/2019 15:41, David Brown wrote:
>> On 23/01/2019 15:33, Bart wrote:
>
>
>>> If I try this:
>>>
>>> ichar words=strinclude "hello.exe"
>>>
>>> (where hello.exe is a 2.5K file), and translate to C, I get:
>>>
>>> static byte * t_words = (byte*)"MZ";
>>>
>>> A three-character string (the third char with code 0x90 is not shown
>>> here). Even if the translation includes all 2560 bytes using \xx codes
>>> within the string, there still isn't a mechanism to to denote the
>>> length.
>>
>> You are in control of the language and the code generator. Why not make
>> it simple:
>>
>> ichar words = bininclude "hello.exe"
>>
>> Translate to C:
>>
>> enum { words_length = 2560 };
>> const uint8_t words[words_length] = {
>> 0x4c, 0x5a, 0x90, 0x00, ...
>> };
>
> Because it's a bit harder!
It is not rocket science. In comparison to what you have done already,
it should be peanuts.
>
> ('strinclude' is a lexical directive that yields one token - a string
> constant, of type pointer to char; much simpler. That's not to say I
> can't do that, but it hasn't come up yet. It would done like this:
>
> []byte imfiledata = bininclude "fred.jpg"
>
> Once that is done, then the translation to C needs nothing special
> (except that it would generate a {...} data sequence with one byte per
> line, spanning possibly millions of lines).
>
> There would also be an overhead of 64 memory bytes per data byte, in the
> compiler, putting an upper limit on the file sizes, unless I invent some
> special handling. The strinclude version only uses one memory byte per
> data byte.)
>
If a binary file is so big that this overhead is a problem when running
the translator on a modern PC, then it is probably not appropriate to be
including the binary file embedded within the C code. Ignore that
limitation until you find it really is a problem.
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2019-01-23 20:23 +0000 |
| Message-ID | <5342E.189308$ux2.88928@fx25.am4> |
| In reply to | #140123 |
On 23/01/2019 16:18, Bart wrote:
> On 23/01/2019 15:41, David Brown wrote:
>> You are in control of the language and the code generator. Why not make
>> it simple:
>>
>> ichar words = bininclude "hello.exe"
>>
>> Translate to C:
>>
>> enum { words_length = 2560 };
>> const uint8_t words[words_length] = {
>> 0x4c, 0x5a, 0x90, 0x00, ...
>> };
>
> Because it's a bit harder!
>
> ('strinclude' is a lexical directive that yields one token - a string
> constant, of type pointer to char; much simpler. That's not to say I
> can't do that, but it hasn't come up yet. It would done like this:
>
> []byte imfiledata = bininclude "fred.jpg"
>
> Once that is done, then the translation to C needs nothing special
> (except that it would generate a {...} data sequence with one byte per
> line, spanning possibly millions of lines).
I managed to get this working with a simple tweak, because I already had
a special kind of string token that is used to initialise a char[] array
rather than char* (my language is strict about that).
Then introducing 'bininclude' which returns that new kind of string was
easy.
This allowed me to write code that embedded sqlite.exe, and wrote it out
again and ran it. That worked in C too, where sqlite was a byte array
with over one million lines:
static byte t_prog[1039360] = {
(uint8)77u,
(uint8)90u,
(uint8)144u,
(uint8)0u,
....
But this quickly gets slow to compile for bigger sizes (a 10MB file =
640MB RAM), because of that 64 bytes to one byte overhead I mentioned.
I can keep the data as a string:
ref char prog=strinclude "c:/cx/big/sqlite3.exe"
but then I need a new feature to obtain the length of the file (which is
needed at compile time; perhaps a compiler variable that returns the
last file size).
By hard-coding the length, I could test this worked. However at the
moment such a string doesn't get translated to C properly.
It's easy to think up uses for such a feature if it can be done
efficiently, such as embedding large resources - including other
programs - directly in a application.
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2019-01-22 17:52 -0600 |
| Message-ID | <hdaf4edpa6h11e8ri44so6hjecmi2h3gni@4ax.com> |
| In reply to | #140095 |
On Tue, 22 Jan 2019 23:02:20 +0100, David Brown
<david.brown@hesbynett.no> wrote:
>On 22/01/2019 18:30, Bart wrote:
>> On 22/01/2019 14:10, David Brown wrote:
>>> On 22/01/2019 13:07, Bart wrote:
>>>> On 22/01/2019 09:55, David Brown wrote:
>>
>>>> That has to be balanced against other approaches such as reading 110,000
>>>> lines from a text file.
>>>
>>> That is going to be a great deal less than 0.1 seconds, at least with an
>>> SSD or an OS that can cache files properly.
>>
>>> And it has to be balanced against doing it properly in C with an
>>> initialised table.
>>
>> Sometimes the data needs to be embedded in the source code. And
>> sometimes the linear block data from a file needs to be arranged into
>> the data structures needed.
>
>I regularly embed files as data in C code. Given your aversion to build
>systems, you'll be horrified to know that for a number of my projects,
>"make" uses Python scripts to turn things like images or html files into
>C files with const arrays of data. These are defined and initialised as
>arrays like
>
> const uint8_t index_html = {
> "\x48\x54\x54\x50\x2f\x31 ...
>
>It is written as an initialised array, declared const. Anything else -
>such as using assignments in a function - would be insane in a small
>embedded system.
I've been somewhat amused by just how large our in-house bin2h program
has become over the last three decades. It's always been C, but it
can now output half a dozen different language formats, and has
options for how things are output for each (for example, it can
generate a .c and a .h pair to keep the large array out of the "real"
compiles, handle multiple files, apply various combinations of static
const or other attributes based on the output language).
The earliest version checked in was 69 lines (which produced only the
format below, although with an extra comma at the end of the
initialization). It's now over 700 lines.
// bin2h file conversion of c-logo.gif
unsigned char c_logo_gif_data[] = {
/* 0x0000 */ 0x47,0x49,0x46,0x38,0x37,0x61,0x48,0x01,
/* 0x0008 */ 0x4c,0x00,0xf7,0x00,0x00,0xff,0xff,0xff,
/* 0x0010 */ 0xe7,0xe7,0xe7,0xde,0xde,0xde,0xd6,0xd6,
/* 0x0018 */ 0xd6,0xce,0xce,0xce,0xc6,0xc6,0xc6,0xbd,
...
/* 0x1700 */ 0x2f,0x11,0x01,0x01,0x00,0x3b
};
long c_logo_gif_len = 5894;
[toc] | [prev] | [next] | [standalone]
| From | Bart <bc@freeuk.com> |
|---|---|
| Date | 2019-01-20 20:17 +0000 |
| Message-ID | <jH41E.575899$Sj4.256857@fx15.am4> |
| In reply to | #140013 |
On 20/01/2019 13:08, Bart wrote:
> Here's another test where each line is in a separate function:
>
> void f1(void) {int a,b=2,c=3,d=4; a=b+c*d;}
> And here are some quick results:
> tiny c 0.2 0.7
> (bcc 0.3 1.6)
More complete tests but concentrating on these two compilers. 'bcc' now
uses a flexible rather than hard-coded symbol table limit:
20K 100K 500K 2000K lines/functions
tcc 0.15 0.6 4.9 41.5
bcc 0.3 1.9 14.8 *OOM
(The last column is for a module with 2 million functions f1(), f2() to
f2000000().)
Tiny C presumably benefits from its single pass as it seems to use very
little memory, so once one function is processed, most of its data is
discarded.
Whereas bcc keeps everything in memory until the whole file has been
processed, and it has multiple passes.
[toc] | [prev] | [next] | [standalone]
| From | BGB <cr88192@hotmail.com> |
|---|---|
| Date | 2019-01-21 00:13 -0600 |
| Message-ID | <q23nus$ga7$1@news.albasani.net> |
| In reply to | #140008 |
On 1/19/2019 9:52 PM, Ian Collins wrote: > On 20/01/2019 13:03, Bart wrote: >> I have an interest in compilers so when I download a new compiler or a >> new language, I often give it a little stress test, which is just lots >> of repeated lines, just to see how it copes. >> >> I've assembled a bunch of such tests here, mostly for C compilers but >> also for a few other languages that happened to be on my machine: >> >> https://github.com/sal55/mx/blob/master/compilertest.txt >> >> I've tested with blocks of 20K, 100K, 500K and 2M lines of code, all on >> the same PC. > > You would be better off compiling real large files (such as the SQLite > blob) which will test an optimiser. > >> As can be seen, many deal with that effortlessly, while others struggle. > > It really only tests how fast the compiler front end parses stuff into > memory, not how the compiler handles real code. > In my case, I was partly testing my compiler with Doom, Quake, and tested building own 3D engine with it (~ 300 kLOC). Also tested building some video codecs and some other random stuff. Doom and Quake seem reasonably representative, but as can be noted aren't particularly large. As is (on a Ryzen), mine compiles Quake in roughly 2.7 seconds (compiler built with debug settings) and 1.4 seconds (built with optimization). Building Doom takes approx 1.9s (debug) and 0.9s (opt). Current memory footprint to build Quake is 190MB, and for Doom is 164MB. A bulk of the memory use tends to be AST nodes. Note: AST nodes are key/value style; not tagged-union style. So, ASTs are basically trees of key/value nodes, with 16-bit values encoding the key name and value type, and a 64 bit value field. As such, memory usage will be higher with larger translation units, but the AST nodes are freed and reused between each translation unit. Time usage is a bit more varied, but some effort was put into generally trying to make things efficient. File loading is kinda expensive, but since the compiler handles all the translation units together it can cache files between TUs (this is mostly relevant for headers). In the frontend preprocess/parse/compile is otherwise pretty typical. Everything merges together in the backend, but in the frontend translation units are handled independently. Binary sizes (static-linked, PE/COFF variant, custom ISA): Doom: 278K Quake: 304K ISA is a RISC variant (load/store architecture with 32 GPRs) with variable-length instructions (16/32/48 bit). It also has some useful addressing modes (eg: PC relative and scaled index), though not quite as fancy as in x86 or ARM (but fancier than RISC-V or MIPS). Code density seems to be "roughly in the same general area" as 32-bit x86 and Thumb2. Note that the compiler uses some aggressive space saving trickery in this case, but otherwise its optimization capabilities are "kinda meh". Code generation neither particularly great, nor particularly terrible (generally still a lot better than typical debug-build output in any case). Compiler is generally able to keep values in registers and will reasonably straightforwardly translate the C code into corresponding machine code (it has relatively few "clever" optimizations). I suspect a decent GCC port or similar could probably do a better job here (I went with my own compiler as it looks like adding a new backend to GCC would be a pretty big project). I generally verify that the generated binaries work as expected by testing them via an emulator. I have been working some on performance, but performance (in Quake) is generally pretty bad much under 100 mips or so (comparable to Doom at around 30 mips), both cases giving roughly 10 fps (or ~ 10M and 3M instructions per frame). Not sure, but this still seems a bit weak. I have been on the fence as to whether an x86-64 target would make sense. For the most part, C is C, and it would be pretty hard to compete with MSVC / Visual Studio (and making it able to produce PDB's and use the VS debugger looks like an uphill battle). The main possible use it could have is if I wanted a natively compiled version of my BGBScript2 language, but even this is kinda meh. The main alternative (under possible consideration) is making my compiler accept a sort of faux C# (then have a common subset that works in both BGBCC and Visual Studio). In this case, things are similar enough (between BS2 and C#) to where I could possibly gloss some of the differences (in the parser). Most notable difference is that C# is garbage collected (whereas BS2 is not) and have some differences regarding how memory management and object lifetime work (such as BS2 having objects and arrays which have automatic storage duration). Straightforwardly mapping C# to BS2 (without adding a GC or similar) would likely result in fairly significant memory leaks. Not sure of a good solution which wouldn't involve a lot of boilerplate (with the goal of the code still being usable in VS).
[toc] | [prev] | [standalone]
Page 8 of 8 — ← Prev page 1 2 3 4 5 6 7 [8]
Back to top | Article view | comp.lang.c
csiph-web