Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #108589 > unrolled thread
| Started by | joel.rees@gmail.com |
|---|---|
| First post | 2017-04-27 03:13 -0700 |
| Last post | 2017-04-30 22:05 -0700 |
| Articles | 20 on this page of 127 — 21 participants |
Back to article view | Back to comp.lang.c
Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-04-27 03:13 -0700
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-04-27 03:41 -0700
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-27 11:59 +0100
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-04-27 14:35 -0700
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-27 15:13 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-28 00:58 +0200
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-27 16:44 -0700
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-04-27 20:04 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-28 08:53 +0200
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-04-28 08:23 -0700
Re: Is this code considered to transgress the signed overflow purism? Manfred <noname@invalid.add> - 2017-04-28 18:05 +0200
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-28 09:22 -0700
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-28 12:24 -0700
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-29 00:03 +0100
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-04-28 16:37 -0700
Re: Is this code considered to transgress the signed overflow purism? David Kleinecke <dkleinecke@gmail.com> - 2017-04-28 17:09 -0700
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-04-28 17:34 -0700
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-29 01:43 +0100
Re: Is this code considered to transgress the signed overflow purism? David Kleinecke <dkleinecke@gmail.com> - 2017-04-28 21:21 -0700
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-04-29 02:04 -0700
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-29 11:46 +0100
Re: Is this code considered to transgress the signed overflow purism? Robert Wessel <robertwessel2@yahoo.com> - 2017-04-30 12:05 -0500
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-29 11:33 +0100
Re: Is this code considered to transgress the signed overflow purism? David Kleinecke <dkleinecke@gmail.com> - 2017-04-29 08:26 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-29 17:58 +0200
Re: Is this code considered to transgress the signed overflow purism? David Kleinecke <dkleinecke@gmail.com> - 2017-04-29 09:13 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-30 12:55 +0200
Re: Is this code considered to transgress the signed overflow purism? David Kleinecke <dkleinecke@gmail.com> - 2017-04-30 09:17 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-30 20:35 +0200
Re: Is this code considered to transgress the signed overflow purism? David Kleinecke <dkleinecke@gmail.com> - 2017-04-30 15:39 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-05-01 16:21 +0200
Re: Is this code considered to transgress the signed overflow purism? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2017-05-02 06:35 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-05-02 16:29 +0200
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-29 20:58 +0100
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-28 18:43 +0200
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-04-28 14:09 +0100
Re: Is this code considered to transgress the signed overflow purism? scott@slp53.sl.home (Scott Lurndal) - 2017-04-28 14:23 +0000
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-04-28 16:17 +0100
Re: Is this code considered to transgress the signed overflow purism? scott@slp53.sl.home (Scott Lurndal) - 2017-04-28 15:55 +0000
Re: Is this code considered to transgress the signed overflow purism? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2017-04-28 19:11 -0700
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-29 11:23 +0100
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-04-29 11:31 +0100
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-29 12:01 +0100
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-04-29 12:47 +0100
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-29 15:20 +0200
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-04-29 15:22 +0100
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-29 16:52 +0200
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-29 15:18 +0100
Re: Is this code considered to transgress the signed overflow purism? Jean-Marc Bourguet <jm@bourguet.org> - 2017-04-29 14:25 +0200
Re: Is this code considered to transgress the signed overflow purism? Jerry Stuckle <jstucklex@attglobal.net> - 2017-04-29 08:05 -0400
Re: Is this code considered to transgress the signed overflow purism? Gareth Owen <gwowen@gmail.com> - 2017-04-29 13:34 +0100
Re: Is this code considered to transgress the signed overflow purism? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2017-04-29 05:55 -0700
Re: Is this code considered to transgress the signed overflow purism? GOTHIER Nathan <nathan.gothier@gmail.com> - 2017-04-29 15:11 +0200
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-29 15:24 +0200
Re: Is this code considered to transgress the signed overflow purism? Gareth Owen <gwowen@gmail.com> - 2017-04-29 14:57 +0100
Re: Is this code considered to transgress the signed overflow purism? asetofsymbols@gmail.com - 2017-05-03 12:17 -0700
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-05-03 16:36 -0700
Re: Is this code considered to transgress the signed overflow purism? asetofsymbols@gmail.com - 2017-05-03 11:26 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-05-03 21:40 +0200
Re: Is this code considered to transgress the signed overflow purism? asetofsymbols@gmail.com - 2017-05-03 23:46 -0700
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-28 08:55 -0700
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-04-27 20:20 -0700
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-04-27 20:26 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-28 10:19 +0200
Re: Is this code considered to transgress the signed overflow purism? James Kuyper <jameskuyper@verizon.net> - 2017-04-28 09:57 -0400
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-28 17:06 +0200
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-04-28 08:38 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-28 18:51 +0200
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-04-29 12:43 -0700
Re: Is this code considered to transgress the signed overflow purism? Tim Rentsch <txr@alumni.caltech.edu> - 2017-04-30 14:02 -0700
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-30 14:25 -0700
Re: Is this code considered to transgress the signed overflow purism? Tim Rentsch <txr@alumni.caltech.edu> - 2017-04-30 15:01 -0700
Re: Is this code considered to transgress the signed overflow purism? James Kuyper <jameskuyper@verizon.net> - 2017-04-28 09:48 -0400
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-04-28 08:07 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-28 18:56 +0200
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-04-28 11:30 -0700
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-28 08:35 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-28 00:54 +0200
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-04-27 21:05 -0700
Re: Is this code considered to transgress the signed overflow purism? David Brown <david.brown@hesbynett.no> - 2017-04-28 10:58 +0200
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-04-28 10:50 +0100
Re: Is this code considered to transgress the signed overflow purism? James Kuyper <jameskuyper@verizon.net> - 2017-04-28 10:01 -0400
Re: Is this code considered to transgress the signed overflow purism? Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-02 05:06 -0700
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-04-28 23:57 +0100
Re: Is this code considered to transgress the signed overflow purism? Tim Rentsch <txr@alumni.caltech.edu> - 2017-04-30 12:28 -0700
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-30 12:41 -0700
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-04-30 21:46 +0100
Re: Is this code considered to transgress the signed overflow purism? Thiago Adams <thiago.adams@gmail.com> - 2017-05-01 05:41 -0700
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-05-01 13:57 +0100
Re: Is this code considered to transgress the signed overflow purism? Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-02 05:30 -0700
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-05-02 16:13 +0100
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-05-02 09:12 -0700
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-05-02 18:15 +0100
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-05-02 11:26 -0700
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-05-02 21:39 +0100
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-05-02 13:53 -0700
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-05-02 14:10 -0700
Re: Is this code considered to transgress the signed overflow purism? bartc <bc@freeuk.com> - 2017-05-02 22:36 +0100
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-05-02 15:27 -0700
Re: Is this code considered to transgress the signed overflow purism? Robert Wessel <robertwessel2@yahoo.com> - 2017-05-03 00:45 -0500
Re: Is this code considered to transgress the signed overflow purism? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-05-03 11:57 +0100
Re: Is this code considered to transgress the signed overflow purism? Robert Wessel <robertwessel2@yahoo.com> - 2017-05-03 13:34 -0500
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-05-03 12:05 -0700
Re: Is this code considered to transgress the signed overflow purism? Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-05 02:58 -0700
Re: Is this code considered to transgress the signed overflow purism? Thiago Adams <thiago.adams@gmail.com> - 2017-05-03 05:26 -0700
Re: Is this code considered to transgress the signed overflow purism? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2017-05-03 05:54 -0700
Re: Is this code considered to transgress the signed overflow purism? Thiago Adams <thiago.adams@gmail.com> - 2017-05-03 06:49 -0700
Re: Is this code considered to transgress the signed overflow purism? Thiago Adams <thiago.adams@gmail.com> - 2017-05-03 06:51 -0700
Re: Is this code considered to transgress the signed overflow purism? jadill33@gmail.com - 2017-05-03 09:03 -0700
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-05-02 14:47 -0700
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-05-03 17:45 -0700
Re: Is this code considered to transgress the signed overflow purism? Tim Rentsch <txr@alumni.caltech.edu> - 2017-04-30 14:42 -0700
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-04-30 23:57 -0700
Re: Is this code considered to transgress the signed overflow purism? Tim Rentsch <txr@alumni.caltech.edu> - 2017-05-02 04:32 -0700
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-05-03 18:20 -0700
Re: Is this code considered to transgress the signed overflow purism? luser droog <luser.droog@gmail.com> - 2017-05-08 23:12 -0700
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-05-09 19:54 -0700
Re: Is this code considered to transgress the signed overflow purism? luser droog <luser.droog@gmail.com> - 2017-05-09 21:21 -0700
Re: Is this code considered to transgress the signed overflow purism? James Kuyper <jameskuyper@verizon.net> - 2017-04-27 10:46 -0400
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-04-27 08:37 -0700
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-27 09:38 -0700
Re: Is this code considered to transgress the signed overflow purism? supercat@casperkitty.com - 2017-04-27 10:17 -0700
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-27 12:10 -0700
Re: Is this code considered to transgress the signed overflow purism? Tim Rentsch <txr@alumni.caltech.edu> - 2017-04-30 13:50 -0700
Re: Is this code considered to transgress the signed overflow purism? Keith Thompson <kst-u@mib.org> - 2017-04-30 14:11 -0700
Re: Is this code considered to transgress the signed overflow purism? Tim Rentsch <txr@alumni.caltech.edu> - 2017-04-30 14:44 -0700
Re: Is this code considered to transgress the signed overflow purism? joel.rees@gmail.com - 2017-04-30 22:05 -0700
Page 6 of 7 — ← Prev page 1 2 3 4 5 [6] 7 Next page →
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-05-03 11:57 +0100 |
| Message-ID | <87y3uegqc6.fsf@bsb.me.uk> |
| In reply to | #109086 |
Robert Wessel <robertwessel2@yahoo.com> writes: > On Tue, 2 May 2017 22:36:43 +0100, bartc <bc@freeuk.com> wrote: > >> #if sizeof(float)==4 <snip> >>On 02/05/2017 22:10, Keith Thompson wrote: <snip> >>> I don't recall that I've ever needed such macros myself, but if >>> they're sufficiently useful I wouldn't object to adding them in a >>> future standard. >> >>I've needed to know the size of a pointer. The size of an int tends to >>be 4, but long can be variable so that can be useful to know too. > > Couldn't most or all of that be done more simply with some predefined > macros? Or ones defined in stdint.h and such? And, very often, if C99 or later can be assumed, the whole thing can be avoided by using stdint.h. Much of the code I've seen that does this kind of testing wants, say, an integer big enough to hold a pointer (intptr_t), or the integer type with the widest range (intmax_t), or at least 32 bits (int_least32_t), and so on. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Robert Wessel <robertwessel2@yahoo.com> |
|---|---|
| Date | 2017-05-03 13:34 -0500 |
| Message-ID | <a78kgchf9l62l2d1n7t0ni7t4pg9adg8gu@4ax.com> |
| In reply to | #109096 |
On Wed, 03 May 2017 11:57:45 +0100, Ben Bacarisse
<ben.usenet@bsb.me.uk> wrote:
>Robert Wessel <robertwessel2@yahoo.com> writes:
>
>> On Tue, 2 May 2017 22:36:43 +0100, bartc <bc@freeuk.com> wrote:
>>
>>> #if sizeof(float)==4
><snip>
>>>On 02/05/2017 22:10, Keith Thompson wrote:
><snip>
>>>> I don't recall that I've ever needed such macros myself, but if
>>>> they're sufficiently useful I wouldn't object to adding them in a
>>>> future standard.
>>>
>>>I've needed to know the size of a pointer. The size of an int tends to
>>>be 4, but long can be variable so that can be useful to know too.
>>
>> Couldn't most or all of that be done more simply with some predefined
>> macros? Or ones defined in stdint.h and such?
>
>And, very often, if C99 or later can be assumed, the whole thing can be
>avoided by using stdint.h. Much of the code I've seen that does this
>kind of testing wants, say, an integer big enough to hold a pointer
>(intptr_t), or the integer type with the widest range (intmax_t), or at
>least 32 bits (int_least32_t), and so on.
Sstdint.h answers a fair number of those sorts of questions, but it
doesn't really provide a good way to find out what sizeof(int) is, and
that sort of thing is occasionally useful. Some additions to stdint.h
(and float.h), would be a simple way to get some of that information
(as opposed to adding a restricted form of sizeof to the
preprocessor). Some additional #defines to classify some
characteristics of the implementation ("#define
USES_CONVENTIONAL_TWOS_COMPLEMENT") would be nice too.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2017-05-03 12:05 -0700 |
| Message-ID | <ln4lx1g3qj.fsf@kst-u.example.com> |
| In reply to | #109122 |
Robert Wessel <robertwessel2@yahoo.com> writes:
> On Wed, 03 May 2017 11:57:45 +0100, Ben Bacarisse
> <ben.usenet@bsb.me.uk> wrote:
>>Robert Wessel <robertwessel2@yahoo.com> writes:
>>> On Tue, 2 May 2017 22:36:43 +0100, bartc <bc@freeuk.com> wrote:
>>>> #if sizeof(float)==4
>><snip>
>>>>On 02/05/2017 22:10, Keith Thompson wrote:
>><snip>
>>>>> I don't recall that I've ever needed such macros myself, but if
>>>>> they're sufficiently useful I wouldn't object to adding them in a
>>>>> future standard.
>>>>
>>>>I've needed to know the size of a pointer. The size of an int tends to
>>>>be 4, but long can be variable so that can be useful to know too.
>>>
>>> Couldn't most or all of that be done more simply with some predefined
>>> macros? Or ones defined in stdint.h and such?
>>
>>And, very often, if C99 or later can be assumed, the whole thing can be
>>avoided by using stdint.h. Much of the code I've seen that does this
>>kind of testing wants, say, an integer big enough to hold a pointer
>>(intptr_t), or the integer type with the widest range (intmax_t), or at
>>least 32 bits (int_least32_t), and so on.
>
>
> Sstdint.h answers a fair number of those sorts of questions, but it
> doesn't really provide a good way to find out what sizeof(int) is, and
> that sort of thing is occasionally useful. Some additions to stdint.h
> (and float.h), would be a simple way to get some of that information
> (as opposed to adding a restricted form of sizeof to the
> preprocessor). Some additional #defines to classify some
> characteristics of the implementation ("#define
> USES_CONVENTIONAL_TWOS_COMPLEMENT") would be nice too.
In particular:
#if UINT_MAX == 4294967295 && CHAR_BIT == 8
puts("sizeof (unsigned) is *probably* 4");
#endif
but there isn't enough information in <limits.h> to detect padding bits,
which affect sizeof (unsigned) but not UINT_MAX.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-05-05 02:58 -0700 |
| Message-ID | <kfnlgqbwrop.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #109126 |
Keith Thompson <kst-u@mib.org> writes:
> Robert Wessel <robertwessel2@yahoo.com> writes:
>> On Wed, 03 May 2017 11:57:45 +0100, Ben Bacarisse
>> <ben.usenet@bsb.me.uk> wrote:
>>> Robert Wessel <robertwessel2@yahoo.com> writes:
>>>> On Tue, 2 May 2017 22:36:43 +0100, bartc <bc@freeuk.com> wrote:
>>>>> #if sizeof(float)==4
>>>
>>> <snip>
>>>
>>>>> On 02/05/2017 22:10, Keith Thompson wrote:
>>>
>>> <snip>
>>>
>>>>>> I don't recall that I've ever needed such macros myself, but if
>>>>>> they're sufficiently useful I wouldn't object to adding them in a
>>>>>> future standard.
>>>>>
>>>>> I've needed to know the size of a pointer. The size of an int tends to
>>>>> be 4, but long can be variable so that can be useful to know too.
>>>>
>>>> Couldn't most or all of that be done more simply with some predefined
>>>> macros? Or ones defined in stdint.h and such?
>>>
>>> And, very often, if C99 or later can be assumed, the whole thing can be
>>> avoided by using stdint.h. Much of the code I've seen that does this
>>> kind of testing wants, say, an integer big enough to hold a pointer
>>> (intptr_t), or the integer type with the widest range (intmax_t), or at
>>> least 32 bits (int_least32_t), and so on.
>>
>> Sstdint.h answers a fair number of those sorts of questions, but it
>> doesn't really provide a good way to find out what sizeof(int) is, and
>> that sort of thing is occasionally useful. Some additions to stdint.h
>> (and float.h), would be a simple way to get some of that information
>> (as opposed to adding a restricted form of sizeof to the
>> preprocessor). Some additional #defines to classify some
>> characteristics of the implementation ("#define
>> USES_CONVENTIONAL_TWOS_COMPLEMENT") would be nice too.
>
> In particular:
>
> #if UINT_MAX == 4294967295 && CHAR_BIT == 8
> puts("sizeof (unsigned) is *probably* 4");
> #endif
>
> but there isn't enough information in <limits.h> to detect padding bits,
> which affect sizeof (unsigned) but not UINT_MAX.
As a practical matter sizes computed from <limits.h> information
will almost always be right, and a static check can be used to
detect those rare cases where they aren't. Here is a sketch
for a scheme (disclaimer: not compiled, to say nothing of
tested):
#include <limits.h>
#define INT_SIZE (VALUE_BYTES( INT ) + INT_PADDING_BYTES)
#define UINT_SIZE (VALUE_BYTES( UINT ) + UINT_PADDING_BYTES)
...
#define VALUE_BYTES(p) ((VALUE_BITS(p)-1) / CHAR_BIT + 1)
#define VALUE_BITS(p) MASK_WIDTH( p ## _MAX )
#define MASK_WIDTH(m) ... // shown in a recent posting
#ifndef INT_PADDING_BYTES
#define INT_PADDING_BYTES 0
#endif
#ifndef UINT_PADDING_BYTES
#define UINT_PADDING_BYTES 0
#endif
...
#define CHECK_SIZE(p,t) extern char types_sizes_check[ \
p ## _SIZE == sizeof (t) ? 1 : -1 \
]
CHECK_SIZE( INT, int );
CHECK_SIZE( UINT, unsigned );
...
In those rare cases where the values of, eg, INT_PADDING_BYTES,
are non-zero, there are various ways the appropriate values might
be injected into the compilations. These should be easy enough
to work out so that no further explanation is needed.
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2017-05-03 05:26 -0700 |
| Message-ID | <a3092262-8ff3-43f9-8e6e-899bed19a926@googlegroups.com> |
| In reply to | #109058 |
On Tuesday, May 2, 2017 at 6:36:42 PM UTC-3, Bart wrote: > On 02/05/2017 22:10, Keith Thompson wrote: > > bartc writes: > > > >> However, it was suggested that such a type might give a different sizeof > >> result in a PP expression, compared with a normal expression. That's why > >> I asked for an example. > > > > Which I gave you. 1U is of type unsigned int. In a typical > > implementation, unsigned int might be 4 bytes, but it would be > > treated by the preprocessor as if it were 8 bytes. > > > > The simplest enhancement of the preprocessor to handle > > `sizeof (unsigned int)` would have it yield 8 -- which would not > > be useful. > > We might be talking at cross purposes. > > The preprocessor is one thing; the parser and rest of the compiler is > another. > > How the preprocessors deals with #if expressions, and what type they > might have is its own business. > > But when you ask it to evaluate sizeof(int) (in a possible extension), > then that would necessarily have to be the size of the int used in the > rest of the compiler. > > As an illustration, what should be the sizeof() return here: > > #if sizeof(float)==4 > > The preprocessor doesn't do floating point; this would only be > meaningful and useful for the 'float' type used in the rest of the > compiler. The same with int types. > > I would expect them to be coupled closely enough that the preprocessor > can access the sizes of the standard, built-in types. > > > To make it useful, you'd have to make the preprocessor aware that > > unsigned int has a size of 4 bytes on the target system, overriding > > the current wording of 6.10.1p4. You'd also need to define a > > somewhat arbitrary division between types that are "basic" enough > > for the preprocessor to know their sizes, and types that aren't. > > You'd want to recognize typedefs, so `sizeof (size_t)` would work, > > size_t are harder because typedefs can exist in different scopes. You > don't want to PP to need to know C's block scope rules, otherwise you'd > be writing a back-to-front compiler. > > That's a problem with the language that size_t types have just been > bolted on as a set of macros. But anyway, with size_t, usually the name > of the type gives a clue to the size! > > > I don't recall that I've ever needed such macros myself, but if > > they're sufficiently useful I wouldn't object to adding them in a > > future standard. > > I've needed to know the size of a pointer. The size of an int tends to > be 4, but long can be variable so that can be useful to know too. > I started to think that everything is an implementation detail. In other words, I think it's possible to implement an integrated parser+tokenizer for the C standard as it is. In this case #if sizeof(size_t) will work, if desired. If some difference arises I think the standard should add notes for implementers and give directions to have both integrated.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2017-05-03 05:54 -0700 |
| Message-ID | <58b9f8d3-a79a-49c1-a796-be833d3c5d2e@googlegroups.com> |
| In reply to | #109099 |
On Wednesday, May 3, 2017 at 1:26:58 PM UTC+1, Thiago Adams wrote: > On Tuesday, May 2, 2017 at 6:36:42 PM UTC-3, Bart wrote: > > I started to think that everything is an implementation detail. > In other words, I think it's possible to implement an integrated > parser+tokenizer for the C standard as it is. > In this case #if sizeof(size_t) will work, if desired. > If some difference arises I think the standard should add notes > for implementers and give directions to have both integrated. > The language is designed so that tokenizers and parsers have an easy time (with a slip-up over typedefs). But you can tokenize at a lower level if determined to do so, with extra complexity in the parser.
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2017-05-03 06:49 -0700 |
| Message-ID | <1a2b2c08-8b08-41fb-a8f9-1aacf2dfb634@googlegroups.com> |
| In reply to | #109100 |
On Wednesday, May 3, 2017 at 9:54:56 AM UTC-3, Malcolm McLean wrote:
> On Wednesday, May 3, 2017 at 1:26:58 PM UTC+1, Thiago Adams wrote:
> > On Tuesday, May 2, 2017 at 6:36:42 PM UTC-3, Bart wrote:
> >
> > I started to think that everything is an implementation detail.
> > In other words, I think it's possible to implement an integrated
> > parser+tokenizer for the C standard as it is.
> > In this case #if sizeof(size_t) will work, if desired.
> > If some difference arises I think the standard should add notes
> > for implementers and give directions to have both integrated.
> >
> The language is designed so that tokenizers and parsers have an easy
> time (with a slip-up over typedefs). But you can tokenize at a lower
> level if determined to do so, with extra complexity in the parser.
Another option is to create a new "if" in the language when compiler is required.
But I prefer to keep #if because everyone would understand.
As I said in the other topic, I think most people would not realize
the changes. I would just work.
Microsoft has __if_exists for instance
https://msdn.microsoft.com/en-us/library/x7wy9xh3.aspx
C++ has constexpr if
void do_something() {
if constexpr (the_os == OS::Linux) {
//do something Linuxy
}
else if constexpr (the_os == OS::Mac) {
//do something Appley
}
else if constexpr (the_os == OS::Windows) {
//do something Windowsy
}
//do something general
}
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2017-05-03 06:51 -0700 |
| Message-ID | <28fefcf8-044e-4c71-8d21-f24c70ab0559@googlegroups.com> |
| In reply to | #109102 |
On Wednesday, May 3, 2017 at 10:49:55 AM UTC-3, Thiago Adams wrote: > On Wednesday, May 3, 2017 at 9:54:56 AM UTC-3, Malcolm McLean wrote: > > On Wednesday, May 3, 2017 at 1:26:58 PM UTC+1, Thiago Adams wrote: > > > On Tuesday, May 2, 2017 at 6:36:42 PM UTC-3, Bart wrote: > > > > > > I started to think that everything is an implementation detail. > > > In other words, I think it's possible to implement an integrated > > > parser+tokenizer for the C standard as it is. > > > In this case #if sizeof(size_t) will work, if desired. > > > If some difference arises I think the standard should add notes > > > for implementers and give directions to have both integrated. > > > > > The language is designed so that tokenizers and parsers have an easy > > time (with a slip-up over typedefs). But you can tokenize at a lower > > level if determined to do so, with extra complexity in the parser. > > Another option is to create a new "if" in the language when compiler is required. > But I prefer to keep #if because everyone would understand. > As I said in the other topic, I think most people would not realize > the changes. I would just work. ... Sorry - It would just work.
[toc] | [prev] | [next] | [standalone]
| From | jadill33@gmail.com |
|---|---|
| Date | 2017-05-03 09:03 -0700 |
| Message-ID | <d75dbed7-30ee-454f-852a-d7708459103b@googlegroups.com> |
| In reply to | #109058 |
On Tuesday, May 2, 2017 at 5:36:42 PM UTC-4, Bart wrote: > On 02/05/2017 22:10, Keith Thompson wrote: > > bartc <b...@freeuk.com> writes: > > > >> However, it was suggested that such a type might give a different sizeof > >> result in a PP expression, compared with a normal expression. That's why > >> I asked for an example. > > > > Which I gave you. 1U is of type unsigned int. In a typical > > implementation, unsigned int might be 4 bytes, but it would be > > treated by the preprocessor as if it were 8 bytes. > > > > The simplest enhancement of the preprocessor to handle > > `sizeof (unsigned int)` would have it yield 8 -- which would not > > be useful. > > We might be talking at cross purposes. > > The preprocessor is one thing; the parser and rest of the compiler is > another. > > How the preprocessors deals with #if expressions, and what type they > might have is its own business. > > But when you ask it to evaluate sizeof(int) (in a possible extension), > then that would necessarily have to be the size of the int used in the > rest of the compiler. > > As an illustration, what should be the sizeof() return here: > > #if sizeof(float)==4 > > The preprocessor doesn't do floating point; this would only be > meaningful and useful for the 'float' type used in the rest of the > compiler. The same with int types. > > I would expect them to be coupled closely enough that the preprocessor > can access the sizes of the standard, built-in types. This size configuration problem of declaring preprocessor #define's corresponding to the sizes of types is commonly handled either using a config.h file that is maintained by hand and has to be customized for the build environment you are in, or is created in a dynamic fashion using a tool like autoconf, e.g. 'AC_CHECK_SIZEOF'. Autoconf would generate the #define statements for you in a config.h as a result of AC_CHECK_SIZEOF statements. While you have made it known that you're not a fan of these build systems, I'd hazard a guess that it's likely because of tools like this why this type of preprocessor extension isn't more widely implemented. > > To make it useful, you'd have to make the preprocessor aware that > > unsigned int has a size of 4 bytes on the target system, overriding > > the current wording of 6.10.1p4. You'd also need to define a > > somewhat arbitrary division between types that are "basic" enough > > for the preprocessor to know their sizes, and types that aren't. > > You'd want to recognize typedefs, so `sizeof (size_t)` would work, > > size_t are harder because typedefs can exist in different scopes. You > don't want to PP to need to know C's block scope rules, otherwise you'd > be writing a back-to-front compiler. > > That's a problem with the language that size_t types have just been > bolted on as a set of macros. But anyway, with size_t, usually the name > of the type gives a clue to the size! Typedef's aren't an issue with autoconf, since AC_CHECK_SIZEOF would run the same code snippet in the script to get the size of a type. If you check under the hood, it's basically running a small C program with the detected compiler to get the size of the type provided in the parameter, and then writes a #define statement that corresponds to the value (if the type exists) eventually to a config.h file. So, if you have AC_CHECK_SIZEOF(size_t), you'll get a '#define SIZEOF_SIZE_T X' for that environment. If it's in a particular header, you add the header to the AC_CHECK_SIZEOF command and it inserts those #include statements into the C test program when it gets the size of a type. > > I don't recall that I've ever needed such macros myself, but if > > they're sufficiently useful I wouldn't object to adding them in a > > future standard. > > I've needed to know the size of a pointer. The size of an int tends to > be 4, but long can be variable so that can be useful to know too. I would guess that the sizes of types is a huge motivating factor behind dynamic build configuration systems like autoconf. First, it started out with everyone modifying config.h constantly to build modules for their unique environments, and autoconf grew out of an attempt to automate a large amount of that configuration. I'm sure there's more than a few AC_CHECK_SIZEOF statements out there in the programs or libraries that use autoconf. Best regards, John D.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-05-02 14:47 -0700 |
| Message-ID | <4579a76a-11fa-4d61-b452-c2da5e6ce427@googlegroups.com> |
| In reply to | #109056 |
On Tuesday, May 2, 2017 at 4:10:26 PM UTC-5, Keith Thompson wrote: > A much less complicated solution would be to add some predefined > macros to <limits.h>, such as _SIZEOF_INT, _SIZEOF_LONG, etc., > and probably some similar macros in <stdint.h>. Another approach that might be more generally useful would be to have a construct that is somewhat like "#if", but applied later in compilation and is bound more tightly to the syntax of the underlying language, and able to evaluate compile-time constant expressions, but would still be capable of affecting declarations. For example, if code that may sometimes need to run on resource-constrained systems will need to build a table of indices into a compile-time constant array, it might be useful to have the table be of type uint8_t if the array is 255 items or less, uint16_t if it's 256-65535 items, or uint32_t if it's bigger. The preprocessor would have no way of knowing how big the array is, but an "if" statement would not be able to select an array type based upon the required maximum value. A "late-evaluated" conditional compilation directive could allow tests based on the size of many kinds of objects--not just primitives.
[toc] | [prev] | [next] | [standalone]
| From | joel.rees@gmail.com |
|---|---|
| Date | 2017-05-03 17:45 -0700 |
| Message-ID | <789ddd4a-e623-4656-8b46-1988732bbb6a@googlegroups.com> |
| In reply to | #109033 |
On Wednesday, May 3, 2017 at 2:15:28 AM UTC+9, Bart wrote: > On 02/05/2017 17:12, Keith Thompson wrote: > > bartc <> writes: > > >> Anyway, I don't think this is related to whether or not a specific type, > >> rather than an evaluation of an expression, might be different in the > >> preprocessor. > > > > It is. > > How? > > For preprocessor expressions used in #if, the PP just uses the maximum > int width available, which appears to be long long or 64 bits even when > the compiler has a 32-bit target and 32-bit ints. > > But I don't think the type of expressions used in #if is anything to do > with the types normally used in the code. Unless someone specifically > wants to make use of intmax_t. > > Even then, I can't see how that can be different between preprocessor > and the rest of the compiler, unless someone deliberately redefines > intmax_t. Which they can do for any type, whether the preprocessor is > involved or not. > > -- > bartc Cross-compiling? You might insist that the cross-compiler run the preprocessor as if it were running on the target, I suppose. But there are a lot of people who will be happy to tell you how hard that is. - Joel Rees Ranting randomly: http://reiisi.blogspot.com
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-04-30 14:42 -0700 |
| Message-ID | <kfny3uhzi5g.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #108797 |
Keith Thompson <kst-u@mib.org> writes: > Tim Rentsch <txr@alumni.caltech.edu> writes: > [...] >> For use in pre-processor conditionals, generally <limits.h> is >> needed, because (a) sizeof doesn't work in #if etc, and (b) >> even if it did, the sizes of types are potentially different in >> the pre-processor than they are in the program. > > I'm not sure how meaningful your point (b) is. [.. sizeof > in the pre-processor could use execution types rather than > pre-processor types ..] I mentioned point (b) as a reminder to the unwary, of which I have to count myself as one. When I was first writing a reply to the previous message, I thought it would be possible to get by without using <limits.h>. To do that I used the MASK_WIDTH() macro on (-1UL), and was baffled for longer than I care to admit when I got 8 bytes as the size of unsigned long even though sizeof (unsigned long) is 4 on that platform. Of course once I realized what had happened I just slapped my forehead, but I thought I might save other people some trouble...
[toc] | [prev] | [next] | [standalone]
| From | joel.rees@gmail.com |
|---|---|
| Date | 2017-04-30 23:57 -0700 |
| Message-ID | <b1655cba-4a18-4b5f-8d2e-cb7595e44721@googlegroups.com> |
| In reply to | #108796 |
On Monday, May 1, 2017 at 4:28:58 AM UTC+9, Tim Rentsch wrote:
> joel rees@somewhere writes:
>
> > [some parts re-ordered for continuity]
Thank you for doing that.
> > On Thursday, April 27, 2017 at 7:59:40 PM UTC+9, Ben Bacarisse wrote:
> >> joel rees@somewhere writes:
> >>
> >>> ----------------
> >>> unsigned byteWidth = 8; /* Not depending on limits.h . */
> >>> unsigned byteMask = 0xFF;
> >>> unsigned ulBytes = 4; /* Sane throw-away initial values. */
> >>>
> >>> void setULbytes( void )
> >>> { int i = 0;
> >>> unsigned char chroller = 1;
> >>> unsigned char chMask = 1;
> >>> unsigned long ulroller = 1;
> >>> while ( chroller != 0 )
> >>> { chroller <<= 1;
> >>> chMask = ( chMask << 1 ) | 1;
> >>> ++i;
> >>> }
> >>
> >>> byteWidth = i;
> >>> i = 0;
> >>> while ( ulroller != 0 )
> >>> { ulroller <<= 1;
> >>> ++i;
> >>> }
> >>> ulBytes = i / byteWidth;
> >>> }
> >>
> >> What's wrong with
> >>
> >> ulBytes = sizeof (unsigned long);
> >>
> >> ?
> >
> > Well, since you ask, you're right. Either way requires
> > run-time behavior.
>
> Do you mean the value produced cannot be used as part of a
> pre-processor conditional?
Precisely. (I think.)
> The 'sizeof' method does
> produce a compile-time constant, albeit one that cannot
> be used as part of a pre-processor conditional.
There is a difference?
Oh. Yeah. I guess I want to say I needed a "pre-processor-time
constant."
> >>> Yes, there is a reason I am ignoring limits.h. Maybe not a
> >>> good reason, but I will debate that later.
> >>
> >> I don't think you need limits.h for this.
> >
> > I wanted to be able to use limits.h for it.
>
> Does that mean you weren't able to? Can you explain why that
> was?
I was trying to define a union that would describe all the things
that a C program would need to know could be pushed on a Forth
interpreter stack.
Or something along those lines.
I think I needed to know how many bits wide the resulting union
was. Or something like that. Not so much needing to know, but
needing to be sure the program would compile with a sufficiently
wide stack element size. And be sure that I could get the unions
on and off the stack reliably.
Could not work out a valid pre-processor expression from what was
available at the time in a standard limits.h.
Byte order issues were mixed in there, but I ultimately ignored
the byte order within the stack elements.
> > I really wish the standards committee had instead specified a
> > means of compile-time testing the architecture for the specific
> > corner- and edge-cases and providing a means to either pop up a
> > warning to remind the reader of compiler output that the code
> > wasn't intended to be compiled on that particular architecture, or
> > use conditional compiled sections to deal with the corner-case on
> > those CPUs.
>
> If what you want is a regular compile-time constant (ie, but not
> usable in a pre-processor conditional), that can be done with a
> 'sizeof' expression:
>
> enum { UL_SIZE = sizeof (unsigned long) };
And that would be available way too late.
> For use in pre-processor conditionals, generally <limits.h> is
> needed, because (a) sizeof doesn't work in #if etc, and (b)
> even if it did, the sizes of types are potentially different in
> the pre-processor than they are in the program.
And, since you mention it, I had to work through that question,
too. I'm not sure I solved it.
Ended up using a program to test the architecture and generate a
header file that the header file would include.
And now, since the waste product has hit the fan about the gcc
compiler engineers deciding optimization was such a high priority
they would just start silently disposing of undefined behaviors
and implement implementation defined behaviors with disappearing
code, I'm wondering how long it will be until the program I wrote
to test the architecture will spit out a header where everything
gets defined to empty expressions.
> If what you want is a value that can be used in a pre-processor
> conditional, for the size of one of the integer types defined in
> <limits.h> and/or <stdint.h>, and the headers in question are
> available, these values can be calculated (making reasonable
> assumptions) as illustrated in the following example:
>
> #include <limits.h>
>
> #define MASK_WIDTH( m ) ( 0U + (unsigned)+( \
> (m) /((m)%32767 +1) /32767 %32767 *15 \
> + (m) %32767 /((m)%31 +1) /31 %31 *5 \
> + 4 - 12 / ((m)%31 + 3) \
> ))
>
> #if MASK_WIDTH( ULONG_MAX ) % CHAR_BIT == 0
> #define UL_SIZE_PP (MASK_WIDTH( ULONG_MAX ) / CHAR_BIT)
> #else
> #error Apparently unsigned long has padding bits
> #endif
>
> #if UL_SIZE_PP == 4
> // unsigned long is 4 bytes
> #elif UL_SIZE_PP == 8
> // unsigned long is 8 bytes
> #else
> // huh? unsigned long is neither 4 bytes nor 8 bytes
> #endif
>
> (The assumption is that the number of padding bits is either
> (a) zero, or (b) non-zero modulo the number of bits in an
> unsigned char.)
I didn't do nearly as much math, but that's what I did until I
hit the problem I'm referring to.
> If there isn't a <limits.h> available then you are pretty
> much SOL.
Oh, I used it, just wasn't able to produce the constant I needed
with limits.h by itself.
I don't know whether you want to see the contorted mess, but
the project is here
https://sourceforge.net/projects/bif-c/
the header where I manufactured the union is here
https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/bifu_i.h
the program for generating the header is in this subdirectory
https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/configs/
The preprocessor computed version, similar to what you suggest,
is in r15, here
https://sourceforge.net/p/bif-c/code/15/tree/trunk/bifu_i.h
starting with the comments on line 56.
FWIW.
--
Joel Rees
http://reiisi.blogspot.com
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <txr@alumni.caltech.edu> |
|---|---|
| Date | 2017-05-02 04:32 -0700 |
| Message-ID | <kfna86vze7x.fsf@x-alumni2.alumni.caltech.edu> |
| In reply to | #108848 |
joel.rees@gmail.com writes:
> On Monday, May 1, 2017 at 4:28:58 AM UTC+9, Tim Rentsch wrote:
>> joel rees@somewhere writes:
>>
>>> [some parts re-ordered for continuity]
>
> Thank you for doing that.
>
>>> On Thursday, April 27, 2017 at 7:59:40 PM UTC+9, Ben Bacarisse wrote:
>>>
>>>> joel rees@somewhere writes:
>>>>
>>>>> ----------------
>>>>> unsigned byteWidth = 8; /* Not depending on limits.h . */
>>>>> unsigned byteMask = 0xFF;
>>>>> unsigned ulBytes = 4; /* Sane throw-away initial values. */
>>>>>
>>>>> void setULbytes( void )
>>>>> { int i = 0;
>>>>> unsigned char chroller = 1;
>>>>> unsigned char chMask = 1;
>>>>> unsigned long ulroller = 1;
>>>>> while ( chroller != 0 )
>>>>> { chroller <<= 1;
>>>>> chMask = ( chMask << 1 ) | 1;
>>>>> ++i;
>>>>> }
>>>>>
>>>>> byteWidth = i;
>>>>> i = 0;
>>>>> while ( ulroller != 0 )
>>>>> { ulroller <<= 1;
>>>>> ++i;
>>>>> }
>>>>> ulBytes = i / byteWidth;
>>>>> }
>>>>
>>>> What's wrong with
>>>>
>>>> ulBytes = sizeof (unsigned long);
>>>>
>>>> ?
>>>
>>> Well, since you ask, you're right. Either way requires
>>> run-time behavior.
>>
>> Do you mean the value produced cannot be used as part of a
>> pre-processor conditional?
>
> Precisely. (I think.)
>
>> The 'sizeof' method does
>> produce a compile-time constant, albeit one that cannot
>> be used as part of a pre-processor conditional.
>
> There is a difference?
>
> Oh. Yeah. I guess I want to say I needed a "pre-processor-time
> constant."
>
>>>>> Yes, there is a reason I am ignoring limits.h. Maybe not a
>>>>> good reason, but I will debate that later.
>>>>
>>>> I don't think you need limits.h for this.
>>>
>>> I wanted to be able to use limits.h for it.
>>
>> Does that mean you weren't able to? Can you explain why that
>> was?
>
> I was trying to define a union that would describe all the things
> that a C program would need to know could be pushed on a Forth
> interpreter stack.
>
> Or something along those lines.
>
> I think I needed to know how many bits wide the resulting union
> was. Or something like that. Not so much needing to know, but
> needing to be sure the program would compile with a sufficiently
> wide stack element size. And be sure that I could get the unions
> on and off the stack reliably.
>
> Could not work out a valid pre-processor expression from what was
> available at the time in a standard limits.h.
>
> [...]
>
> Ended up using a program to test the architecture and generate a
> header file that the header file would include.
Okay...
>> [...how to calculate bit widths in the pre-processor]
>
> I didn't do nearly as much math, but that's what I did until I
> hit the problem I'm referring to.
>
>> If there isn't a <limits.h> available then you are pretty
>> much SOL.
>
> Oh, I used it, just wasn't able to produce the constant I needed
> with limits.h by itself.
>
> I don't know whether you want to see the contorted mess, but
> the project is here
>
> https://sourceforge.net/projects/bif-c/
>
> the header where I manufactured the union is here
>
> https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/bifu_i.h
>
> the program for generating the header is in this subdirectory
>
> https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/configs/
>
> The preprocessor computed version, similar to what you suggest,
> is in r15, here
>
> https://sourceforge.net/p/bif-c/code/15/tree/trunk/bifu_i.h
>
> starting with the comments on line 56.
I downloaded the specific files you mentioned, and then the
entire project. Looking through the code, AFAICT it should
be fairly straightforward to do what you want to do using
just <limits.h> and pre-processor tests (and #defines, etc).
Of course I may have missed or misunderstood something.
Can you explain more specifically what value you need to
produce? It would help if you could give both a description
and an example case (or cases plural) along with the value(s)
for the example case(s).
[toc] | [prev] | [next] | [standalone]
| From | joel.rees@gmail.com |
|---|---|
| Date | 2017-05-03 18:20 -0700 |
| Message-ID | <c06e07f8-dca7-439e-afbd-9370cdac2699@googlegroups.com> |
| In reply to | #109020 |
On Tuesday, May 2, 2017 at 8:32:25 PM UTC+9, Tim Rentsch wrote:
> joel rees@somewhere writes:
>
> > On Monday, May 1, 2017 at 4:28:58 AM UTC+9, Tim Rentsch wrote:
> >> joel rees@somewhere writes:
> >>
> >>> [some parts re-ordered for continuity]
> >
> > Thank you for doing that.
> >
> >>> On Thursday, April 27, 2017 at 7:59:40 PM UTC+9, Ben Bacarisse wrote:
> >>>
> >>>> joel rees@somewhere writes:
> >>>>
> >>>>> ----------------
> >>>>> unsigned byteWidth = 8; /* Not depending on limits.h . */
> >>>>> unsigned byteMask = 0xFF;
> >>>>> unsigned ulBytes = 4; /* Sane throw-away initial values. */
> >>>>>
> >>>>> void setULbytes( void )
> >>>>> { int i = 0;
> >>>>> unsigned char chroller = 1;
> >>>>> unsigned char chMask = 1;
> >>>>> unsigned long ulroller = 1;
> >>>>> while ( chroller != 0 )
> >>>>> { chroller <<= 1;
> >>>>> chMask = ( chMask << 1 ) | 1;
> >>>>> ++i;
> >>>>> }
> >>>>>
> >>>>> byteWidth = i;
> >>>>> i = 0;
> >>>>> while ( ulroller != 0 )
> >>>>> { ulroller <<= 1;
> >>>>> ++i;
> >>>>> }
> >>>>> ulBytes = i / byteWidth;
> >>>>> }
> >>>>
> >>>> What's wrong with
> >>>>
> >>>> ulBytes = sizeof (unsigned long);
> >>>>
> >>>> ?
> >>>
> >>> Well, since you ask, you're right. Either way requires
> >>> run-time behavior.
> >>
> >> Do you mean the value produced cannot be used as part of a
> >> pre-processor conditional?
> >
> > Precisely. (I think.)
> >
> >> The 'sizeof' method does
> >> produce a compile-time constant, albeit one that cannot
> >> be used as part of a pre-processor conditional.
> >
> > There is a difference?
> >
> > Oh. Yeah. I guess I want to say I needed a "pre-processor-time
> > constant."
> >
> >>>>> Yes, there is a reason I am ignoring limits.h. Maybe not a
> >>>>> good reason, but I will debate that later.
> >>>>
> >>>> I don't think you need limits.h for this.
> >>>
> >>> I wanted to be able to use limits.h for it.
> >>
> >> Does that mean you weren't able to? Can you explain why that
> >> was?
> >
> > I was trying to define a union that would describe all the things
> > that a C program would need to know could be pushed on a Forth
> > interpreter stack.
> >
> > Or something along those lines.
> >
> > I think I needed to know how many bits wide the resulting union
> > was. Or something like that. Not so much needing to know, but
> > needing to be sure the program would compile with a sufficiently
> > wide stack element size. And be sure that I could get the unions
> > on and off the stack reliably.
> >
> > Could not work out a valid pre-processor expression from what was
> > available at the time in a standard limits.h.
> >
> > [...]
> >
> > Ended up using a program to test the architecture and generate a
> > header file that the header file would include.
>
> Okay...
>
> >> [...how to calculate bit widths in the pre-processor]
> >
> > I didn't do nearly as much math, but that's what I did until I
> > hit the problem I'm referring to.
> >
> >> If there isn't a <limits.h> available then you are pretty
> >> much SOL.
> >
> > Oh, I used it, just wasn't able to produce the constant I needed
> > with limits.h by itself.
> >
> > I don't know whether you want to see the contorted mess, but
> > the project is here
> >
> > https://sourceforge.net/projects/bif-c/
> >
> > the header where I manufactured the union is here
> >
> > https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/bifu_i.h
> >
> > the program for generating the header is in this subdirectory
> >
> > https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/configs/
> >
> > The preprocessor computed version, similar to what you suggest,
> > is in r15, here
> >
> > https://sourceforge.net/p/bif-c/code/15/tree/trunk/bifu_i.h
> >
> > starting with the comments on line 56.
>
> I downloaded the specific files you mentioned, and then the
> entire project. Looking through the code, AFAICT it should
> be fairly straightforward to do what you want to do using
> just <limits.h> and pre-processor tests (and #defines, etc).
I should have warned you in advance that the code is not in a
very ideal state. Apologies for that. (And thanks for taking
a look at it.)
It was straightforward enough, I suppose, to use the preprocessor
tests as I had them up until r15. But I ran into problems going
to 64 bit architectures at the same time as adding LSB first
byte order support.
> Of course I may have missed or misunderstood something.
And my memory of what I was working against is kind of fuzzy.
> Can you explain more specifically what value you need to
> produce? It would help if you could give both a description
> and an example case (or cases plural) along with the value(s)
> for the example case(s).
IIRC, there were two primary issues.
One was byte order within an integer, which I still have not
bothered solving.
I think I needed to know the size of the char array to put in the
union. But then I decided that it was better to just handle byte
order explicitly in the Forth code, rather than having the
interpreter trying to be too helpful.
The other was trying to have Forth double cells keep the same
order as the native byte order of the processor, which I also
decided I didn't want to do.
I think there were a few other such things.
A lot of it had to do with targeting really old compilers.
For instance, I was trying to keep the code compatible with an
old ca. 1995 Codewarrior (Metrowerks) compiler for the Classic
Macintosh. In those compilers, the standard headers are a bit
more primitive.
(And the differences between the pre-processor and the C
compile phases were a bit more pronounced.)
--
Joel Rees
Ranting randomly:
http://reiisi.blogspot.com
[toc] | [prev] | [next] | [standalone]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2017-05-08 23:12 -0700 |
| Message-ID | <d407ccd8-634e-4a9e-8114-142e537521c5@googlegroups.com> |
| In reply to | #108848 |
On Monday, May 1, 2017 at 1:57:46 AM UTC-5, joel...@gmail.com wrote:
> I don't know whether you want to see the contorted mess, but
> the project is here
>
> https://sourceforge.net/projects/bif-c/
>
> the header where I manufactured the union is here
>
> https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/bifu_i.h
>
> the program for generating the header is in this subdirectory
>
> https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/configs/
>
> The preprocessor computed version, similar to what you suggest,
> is in r15, here
>
> https://sourceforge.net/p/bif-c/code/15/tree/trunk/bifu_i.h
>
> starting with the comments on line 56.
>
> FWIW.
>
I took a peek at some of the code, starting with main(). But it
all looks very very complicated.
I have an interest in interpreters and virtual machines, but I
seem to go about it in a very different manner. From a (perhaps
unhealthily) long sojourn on codegolf.stackexchange.com, I usually
start with a very small prototype and attempt to reduce the
amount of new code needed to add features or functions.
A few examples, which may offer some sort of alternative style
for your consideration. Since the code is a Forth vm, let me
share my super-tiny toy Forth VM that I think is very clever.
By embracing the "virtual" notion, my code doesn't bother with
anything in <limits.h> (perhaps it should do so, a little bit).
Just use 'int'. That's what it's for. The natural word size
for the implementation, /whatever that is/.
https://groups.google.com/d/msg/comp.lang.c/WGSl7ERMu1U/jmFkuRCQTfgJ
/* Token-Threaded-Code Virtual Machine */
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#define size(a) (sizeof a/sizeof*a)
typedef int16_t cell;
cell lopad[10];
cell m[10000]; /* memory */
cell hipad[10];
cell w; /* work */
cell i; /* instruction */
cell s = 0; /* parameter stack grows up */
cell r = size(m)-1; /* return stack grows down */
cell ss; /* stack segment */
#define OPS(_) \
_(zero, { w = 0; } ) \
_(push, { m[ss+s++] = w; } ) \
_(pop, { w = m[--s+ss]; } ) \
_(add, { w += m[--s+ss]; } ) \
_(sub, { w -= m[--s+ss]; } ) \
_(print, { printf("%hu\n", w); } ) \
_(call, { m[r--] = i; \
i = m[i]; } ) \
_(jump, { i = w; } ) \
_(ret, { i = m[++r]; } ) \
_(quit, { exit(w); } ) \
#define VFUN(a, b) \
void a (void) b
OPS(VFUN)
void noop (void) { } /* noop is 'no operation' AND 'no. of operators'
*/
void (*ftab[])(void) = {
#define RFUN(a, b) \
a ,
OPS(RFUN) noop /* noop brackets the otherwise trailing comma */
};
enum opcode {
#define EFUN(a, b) \
op_ ## a ,
OPS(EFUN) op_noop /* noop brackets the otherwise trailing comma */
};
char *stab[] = {
#define SFUN(a, b) \
#a ,
OPS(SFUN) "noop"
};
int main (int argc, char **argv) {
w = 0; jump(); /* start of program */
m[w++] = op_call;
m[w++] = 10;
m[w++] = op_quit;
w = 10; /* double procedure */
m[w++] = op_push;
m[w++] = op_add;
m[w++] = op_print;
m[w++] = op_ret;
ss = 20; /* put stack above program */
w = 5; /* initial value */
do {
/*
printf("%s\n", stab[ m[i] ]);
*/
++i;
ftab[ m[i-1] ]();
if ( (s < 0)
|| (r > size(m)-1)
|| (s == r)
)
{
fprintf(stderr, "ERROR\n");
exit(1);
}
} while(1);
return 0;
}
Some other fun ones can be found around codegolf.SE, notably
the 8086 subset in 350 lines (super-dense, but not golfed per se):
https://codegolf.stackexchange.com/a/52902/2381
Another unsolicited tip I received many years ago and am still
learning to follow is:
Break it up into small functions.
Super small functions. There's a saying that there are 2 ways to
design a system:
1. make it so simple that there are obviously no deficiencies
2. make it so complication that there are no obvious deficiences
Small functions give you the first choice. A 2- or 3- line function
with a good name can be easily scanned and verified so the brain
can move on to the next task.
Hope some of this is helpful, albeit not very targeted. I really
tried digging into your code, but I started drowning before I got
very deep. I have a sense that a lot of the hardware details and
unnecessary and causing a great deal of extra complexity. But I may
be mistaken, as admittedly I did not grok through very far.
droog
--
'droog' is russian for "friend"
cf. the works of Anthony Burgess
[toc] | [prev] | [next] | [standalone]
| From | joel.rees@gmail.com |
|---|---|
| Date | 2017-05-09 19:54 -0700 |
| Message-ID | <a9541b18-9f4c-40ac-8df6-90e74b5b28ed@googlegroups.com> |
| In reply to | #109563 |
On Tuesday, May 9, 2017 at 3:12:56 PM UTC+9, luser droog wrote:
> On Monday, May 1, 2017 at 1:57:46 AM UTC-5, joel...@somewhere wrote:
>
> > I don't know whether you want to see the contorted mess, but
> > the project is here
> >
> > https://sourceforge.net/projects/bif-c/
> >
> > the header where I manufactured the union is here
> >
> > https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/bifu_i.h
> >
> > the program for generating the header is in this subdirectory
> >
> > https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/configs/
> >
> > The preprocessor computed version, similar to what you suggest,
> > is in r15, here
> >
> > https://sourceforge.net/p/bif-c/code/15/tree/trunk/bifu_i.h
> >
> > starting with the comments on line 56.
> >
> > FWIW.
> >
>
> I took a peek at some of the code, starting with main(). But it
> all looks very very complicated.
Thank you for looking at the code. Yes, it is complicated, and
the file organization makes it look even more so.
Part of the reason for the file organization is that I was trying
to restrict myself to a re-implementation of an interpreter I had
written previously in 6809 assembler. And the 6809 assembler source
code was written using a rather primitive microcomputer programming
environment that was already ancient when I used it. Source code
file size limits and some other stuff pushed me to move code to
places it really did not belong. (Lack of understanding also played
a part, but real programmers never admit that, so I won't. ;)
> I have an interest in interpreters and virtual machines, but I
> seem to go about it in a very different manner. From a (perhaps
> unhealthily) long sojourn on codegolf.stackexchange.com, I usually
> start with a very small prototype and attempt to reduce the
> amount of new code needed to add features or functions.
Recreational programming is fun. I do that, too, sometimes.
> A few examples, which may offer some sort of alternative style
> for your consideration. Since the code is a Forth vm, let me
> share my super-tiny toy Forth VM that I think is very clever.
> By embracing the "virtual" notion, my code doesn't bother with
> anything in <limits.h> (perhaps it should do so, a little bit).
> Just use 'int'. That's what it's for. The natural word size
> for the implementation, /whatever that is/.
But you do use stdint.h. It isn't available for some of the compilers
I was targeting.
> https://groups.google.com/d/msg/comp.lang.c/WGSl7ERMu1U/jmFkuRCQTfgJ
>
> /* Token-Threaded-Code Virtual Machine */
> #include <stdint.h>
> #include <stdio.h>
> #include <stdlib.h>
>
> #define size(a) (sizeof a/sizeof*a)
>
> typedef int16_t cell;
That, of course, is not int. And it's 16 bits, isn't it?
> cell lopad[10];
> cell m[10000]; /* memory */
> cell hipad[10];
> cell w; /* work */
> cell i; /* instruction */
> cell s = 0; /* parameter stack grows up */
> cell r = size(m)-1; /* return stack grows down */
So you don't try to use the CPU's stack as the return stack. Probably
wise.
Not sure I care for a parameter stack that grows upwards.
> cell ss; /* stack segment */
And I thought, threading? But, no, you're using that to define your
heap.
> #define OPS(_) \
> _(zero, { w = 0; } ) \
> _(push, { m[ss+s++] = w; } ) \
> _(pop, { w = m[--s+ss]; } ) \
> _(add, { w += m[--s+ss]; } ) \
> _(sub, { w -= m[--s+ss]; } ) \
> _(print, { printf("%hu\n", w); } ) \
> _(call, { m[r--] = i; \
> i = m[i]; } ) \
> _(jump, { i = w; } ) \
> _(ret, { i = m[++r]; } ) \
> _(quit, { exit(w); } ) \
>
Nice use of a macro to collect a list of short functions that conform
to a single declaration fingerprint.
It seems to be missing several of the primitives that I would think
are necessary to bootstrap a real Forth, but I assume it was not
your intent to bootstrap a real Forth.
> #define VFUN(a, b) \
> void a (void) b
> OPS(VFUN)
> void noop (void) { } /* noop is 'no operation' AND 'no. of operators'
> */
>
> void (*ftab[])(void) = {
> #define RFUN(a, b) \
> a ,
> OPS(RFUN) noop /* noop brackets the otherwise trailing comma */
> };
There's your i-code, or virtual instruction table. Since there are so
few, they could even be byte-codes.
I'm wondering why you bury the macro that generates the array inside
the array declaration. Is that just to make it clear that the macro
isn't intended to be used anywhere else?
> enum opcode {
> #define EFUN(a, b) \
> op_ ## a ,
> OPS(EFUN) op_noop /* noop brackets the otherwise trailing comma */
> };
And the i-codes, instead of using raw function pointers.
Generating by macro is good. Hand generating the i-codes
will usually lead to errors.
Most of the time, using i-codes is considered a good thing,
and the indirection through the i-code table only slows you
down ten or twenty cycles per leaf call.
> char *stab[] = {
> #define SFUN(a, b) \
> #a ,
> OPS(SFUN) "noop"
> };
And there's your symbol table as a linear list. And it isn't in your
heap.
At least, I think that's your symbol table. I don't seem to see you
using it, however. Oh, well, except for your debug printf().
And it doesn't appear to be extensible without adding C source code.
I used a binary tree for the symbol table because I wanted to play
with binary trees, and because the teacher said I had to do something
that was obviously not just using m4 to convert 6800 code to 6809
code when I wrote the interpreter which I later converted to the one
you were kind enough to look at.
(I should have argued that I didn't have a machine-readable copy, and
that I wanted to actually explore an existing Forth environment
instead of going off half-cocked, and just adding math to the BNF
interpreter I had written for a sophomore class. -- And he would have
told me to add the math to the BNF and explore the Forth on my own
time, which would have been the better solution, really. :-/)
Binary trees are a bit harder to build using macros. And harder to
maintain in pre-built form. Ultimately, I let the table become an
unbalanced, unsorted tree and used a bit of start-up code to sort
and balance the table.
> int main (int argc, char **argv) {
>
> w = 0; jump(); /* start of program */
Odd placement of the jump to cold start -- jump to your program
before you copy it to the heap. Or did I miss something?
> m[w++] = op_call;
> m[w++] = 10;
> m[w++] = op_quit;
>
> w = 10; /* double procedure */
> m[w++] = op_push;
> m[w++] = op_add;
> m[w++] = op_print;
> m[w++] = op_ret;
Simple test program to demonstrate your vm's engine.
> ss = 20; /* put stack above program */
>
> w = 5; /* initial value */
>
> do {
> /*
> printf("%s\n", stab[ m[i] ]);
> */
> ++i;
> ftab[ m[i-1] ]();
>
> if ( (s < 0)
> || (r > size(m)-1)
> || (s == r)
I think I would have made that ( s >= r ).
> )
> {
> fprintf(stderr, "ERROR\n");
> exit(1);
> }
> } while(1);
>
> return 0;
> }
Okay. You defined a partial vm and partially tested it.
If I had been keeping a repository of all the code I wrote while
I was designing the virtual machine for bif-c, one of the dead-
end branches would have had something that looked a little like
what you've written here.
So it could be a good first step.
However, since the list of primitives necessary to bootstrap a
real Forth, capable of looking things up in the symbol table,
and of compiling new definitions without the use of a C compiler,
etc., contains more than 50 primitives, and some of those
primitives necessarily contain rather involved code, I have to
wonder whether the macros would not become rather restrictive.
A work-around would be to have several "modules" enclosed in your
macros, and combine them with some start-up code.
I just ended up not trying to use a macro to automatically
collect my primitives. Part of the reason is that I wanted to keep
the definition headers close to the actual definitions in the C
source code.
> Some other fun ones can be found around codegolf.SE, notably
> the 8086 subset in 350 lines (super-dense, but not golfed per se):
>
> https://codegolf.stackexchange.com/a/52902/2381
Gag.
Something I want to do for fun sometime is implement a 6809 emulator,
then extend it to 32 bit math and addressing.
Even just as recreation, implementing as perverse an architecture
as the 8086 is not my definition of fun.
Not that it would be hard. It would not be hard. But plenty of
emulators already exist. If I really want to remember the bad
old days, I can use one of those. 8-9
> Another unsolicited tip I received many years ago and am still
> learning to follow is:
>
> Break it up into small functions.
Funny thing about that.
> Super small functions. There's a saying that there are 2 ways to
> design a system:
>
> 1. make it so simple that there are obviously no deficiencies
> 2. make it so complication that there are no obvious deficiences
>
> Small functions give you the first choice. A 2- or 3- line function
> with a good name can be easily scanned and verified so the brain
> can move on to the next task.
You probably really like Forth, then.
I suppose you must not have ventured into the files with the
primitives. Or maybe you just saw the harder primitives. (Some
things just really cannot be done in two or three lines of
code.)
The start-up code needs to be thoroughly refactored, and it
really could benefit from using the vm itself, but I was in a
hurry when I wrote that and had been writing mostly Java at
the time. Shifting gears was a bit too much trouble. If I can
ever make time, I should fix it.
There are some subtle bugs in my start-up code, and if I use a
bit less cryptic technique for the standard I/O redirection, I
might be able to get it to compile something that runs on Android.
> Hope some of this is helpful, albeit not very targeted. I really
> tried digging into your code, but I started drowning before I got
> very deep. I have a sense that a lot of the hardware details and
> unnecessary and causing a great deal of extra complexity. But I may
> be mistaken, as admittedly I did not grok through very far.
Enjoyed reading your code. Sorry to have subjected you to such a
mess.
> droog
>
> --
> 'droog' is russian for "friend"
> cf. the works of Anthony Burgess
--
Joel Rees
Delusions of reinventing the industry all by myself:
http://defining-computers.blogspot.jp/
[toc] | [prev] | [next] | [standalone]
| From | luser droog <luser.droog@gmail.com> |
|---|---|
| Date | 2017-05-09 21:21 -0700 |
| Message-ID | <8b377f9d-8fed-442e-a060-edff8f68fd22@googlegroups.com> |
| In reply to | #109638 |
On Tuesday, May 9, 2017 at 9:55:16 PM UTC-5, joel...@gmail.com wrote:
> On Tuesday, May 9, 2017 at 3:12:56 PM UTC+9, luser droog wrote:
> > On Monday, May 1, 2017 at 1:57:46 AM UTC-5, joel...@somewhere wrote:
> >
> > > I don't know whether you want to see the contorted mess, but
> > > the project is here
> > >
> > > https://sourceforge.net/projects/bif-c/
> > >
> > > the header where I manufactured the union is here
> > >
> > > https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/bifu_i.h
> > >
> > > the program for generating the header is in this subdirectory
> > >
> > > https://sourceforge.net/p/bif-c/code/HEAD/tree/trunk/configs/
> > >
> > > The preprocessor computed version, similar to what you suggest,
> > > is in r15, here
> > >
> > > https://sourceforge.net/p/bif-c/code/15/tree/trunk/bifu_i.h
> > >
> > > starting with the comments on line 56.
> > >
> > > FWIW.
> > >
> >
> > I took a peek at some of the code, starting with main(). But it
> > all looks very very complicated.
>
> Thank you for looking at the code. Yes, it is complicated, and
> the file organization makes it look even more so.
>
> Part of the reason for the file organization is that I was trying
> to restrict myself to a re-implementation of an interpreter I had
> written previously in 6809 assembler. And the 6809 assembler source
> code was written using a rather primitive microcomputer programming
> environment that was already ancient when I used it. Source code
> file size limits and some other stuff pushed me to move code to
> places it really did not belong. (Lack of understanding also played
> a part, but real programmers never admit that, so I won't. ;)
That all seems reasonable.
> > I have an interest in interpreters and virtual machines, but I
> > seem to go about it in a very different manner. From a (perhaps
> > unhealthily) long sojourn on codegolf.stackexchange.com, I usually
> > start with a very small prototype and attempt to reduce the
> > amount of new code needed to add features or functions.
>
> Recreational programming is fun. I do that, too, sometimes.
>
> > A few examples, which may offer some sort of alternative style
> > for your consideration. Since the code is a Forth vm, let me
> > share my super-tiny toy Forth VM that I think is very clever.
> > By embracing the "virtual" notion, my code doesn't bother with
> > anything in <limits.h> (perhaps it should do so, a little bit).
> > Just use 'int'. That's what it's for. The natural word size
> > for the implementation, /whatever that is/.
>
> But you do use stdint.h. It isn't available for some of the compilers
> I was targeting.
Yes. The code is from a few years ago, obviously incomplete.
And doesn't really illustrate all my claims and maxims.
Relying on 'int' is a later idea which I am using in my APL
interpreter, https://github.com/luser-dr00g/inca/olmec , but,
yeah.
> > https://groups.google.com/d/msg/comp.lang.c/WGSl7ERMu1U/jmFkuRCQTfgJ
> >
> > /* Token-Threaded-Code Virtual Machine */
> > #include <stdint.h>
> > #include <stdio.h>
> > #include <stdlib.h>
> >
> > #define size(a) (sizeof a/sizeof*a)
> >
> > typedef int16_t cell;
>
> That, of course, is not int. And it's 16 bits, isn't it?
>
> > cell lopad[10];
> > cell m[10000]; /* memory */
> > cell hipad[10];
> > cell w; /* work */
> > cell i; /* instruction */
> > cell s = 0; /* parameter stack grows up */
> > cell r = size(m)-1; /* return stack grows down */
>
> So you don't try to use the CPU's stack as the return stack. Probably
> wise.
Yes that's a better example of what I was trying to present.
> Not sure I care for a parameter stack that grows upwards.
>
> > cell ss; /* stack segment */
>
> And I thought, threading? But, no, you're using that to define your
> heap.
>
> > #define OPS(_) \
> > _(zero, { w = 0; } ) \
> > _(push, { m[ss+s++] = w; } ) \
> > _(pop, { w = m[--s+ss]; } ) \
> > _(add, { w += m[--s+ss]; } ) \
> > _(sub, { w -= m[--s+ss]; } ) \
> > _(print, { printf("%hu\n", w); } ) \
> > _(call, { m[r--] = i; \
> > i = m[i]; } ) \
> > _(jump, { i = w; } ) \
> > _(ret, { i = m[++r]; } ) \
> > _(quit, { exit(w); } ) \
> >
>
> Nice use of a macro to collect a list of short functions that conform
> to a single declaration fingerprint.
>
> It seems to be missing several of the primitives that I would think
> are necessary to bootstrap a real Forth, but I assume it was not
> your intent to bootstrap a real Forth.
That was my intent, but I stopped far short of that goal. :(
This was meant to be the "machine" part, and then the forth would
be built on top of that (and perhaps macro-compiled into that
bootstrapping section of main()).
> > #define VFUN(a, b) \
> > void a (void) b
> > OPS(VFUN)
> > void noop (void) { } /* noop is 'no operation' AND 'no. of operators'
> > */
> >
> > void (*ftab[])(void) = {
> > #define RFUN(a, b) \
> > a ,
> > OPS(RFUN) noop /* noop brackets the otherwise trailing comma */
> > };
>
> There's your i-code, or virtual instruction table. Since there are so
> few, they could even be byte-codes.
>
> I'm wondering why you bury the macro that generates the array inside
> the array declaration. Is that just to make it clear that the macro
> isn't intended to be used anywhere else?
That, and I was hoping the formatting would better illustrate what it
was doing. The "op_ ## a," is lined-up like a /real/ element of the enum.
But maybe there are better choices for presentation.
> > enum opcode {
> > #define EFUN(a, b) \
> > op_ ## a ,
> > OPS(EFUN) op_noop /* noop brackets the otherwise trailing comma */
> > };
>
> And the i-codes, instead of using raw function pointers.
>
> Generating by macro is good. Hand generating the i-codes
> will usually lead to errors.
>
> Most of the time, using i-codes is considered a good thing,
> and the indirection through the i-code table only slows you
> down ten or twenty cycles per leaf call.
>
> > char *stab[] = {
> > #define SFUN(a, b) \
> > #a ,
> > OPS(SFUN) "noop"
> > };
>
> And there's your symbol table as a linear list. And it isn't in your
> heap.
>
> At least, I think that's your symbol table. I don't seem to see you
> using it, however. Oh, well, except for your debug printf().
Just a string table. As hinted above, the real symbol table
was going to have been /on a higher level/.
> And it doesn't appear to be extensible without adding C source code.
>
> I used a binary tree for the symbol table because I wanted to play
> with binary trees, and because the teacher said I had to do something
> that was obviously not just using m4 to convert 6800 code to 6809
> code when I wrote the interpreter which I later converted to the one
> you were kind enough to look at.
>
> (I should have argued that I didn't have a machine-readable copy, and
> that I wanted to actually explore an existing Forth environment
> instead of going off half-cocked, and just adding math to the BNF
> interpreter I had written for a sophomore class. -- And he would have
> told me to add the math to the BNF and explore the Forth on my own
> time, which would have been the better solution, really. :-/)
>
> Binary trees are a bit harder to build using macros. And harder to
> maintain in pre-built form. Ultimately, I let the table become an
> unbalanced, unsorted tree and used a bit of start-up code to sort
> and balance the table.
>
> > int main (int argc, char **argv) {
> >
> > w = 0; jump(); /* start of program */
>
> Odd placement of the jump to cold start -- jump to your program
> before you copy it to the heap. Or did I miss something?
It is an odd place. I was probably smirking and "being clever".
Since jump() just does "i = w;", it isn't /wrong/ per se. But it
would probably be less surprising just before the loop starts.
> > m[w++] = op_call;
> > m[w++] = 10;
> > m[w++] = op_quit;
> >
> > w = 10; /* double procedure */
> > m[w++] = op_push;
> > m[w++] = op_add;
> > m[w++] = op_print;
> > m[w++] = op_ret;
>
> Simple test program to demonstrate your vm's engine.
>
> > ss = 20; /* put stack above program */
> >
> > w = 5; /* initial value */
> >
> > do {
> > /*
> > printf("%s\n", stab[ m[i] ]);
> > */
> > ++i;
> > ftab[ m[i-1] ]();
> >
> > if ( (s < 0)
> > || (r > size(m)-1)
> > || (s == r)
>
> I think I would have made that ( s >= r ).
Yes. Better.
> > )
> > {
> > fprintf(stderr, "ERROR\n");
> > exit(1);
> > }
> > } while(1);
> >
> > return 0;
> > }
>
> Okay. You defined a partial vm and partially tested it.
>
> If I had been keeping a repository of all the code I wrote while
> I was designing the virtual machine for bif-c, one of the dead-
> end branches would have had something that looked a little like
> what you've written here.
>
> So it could be a good first step.
>
> However, since the list of primitives necessary to bootstrap a
> real Forth, capable of looking things up in the symbol table,
> and of compiling new definitions without the use of a C compiler,
> etc., contains more than 50 primitives, and some of those
> primitives necessarily contain rather involved code, I have to
> wonder whether the macros would not become rather restrictive.
>
> A work-around would be to have several "modules" enclosed in your
> macros, and combine them with some start-up code.
>
> I just ended up not trying to use a macro to automatically
> collect my primitives. Part of the reason is that I wanted to keep
> the definition headers close to the actual definitions in the C
> source code.
>
> > Some other fun ones can be found around codegolf.SE, notably
> > the 8086 subset in 350 lines (super-dense, but not golfed per se):
> >
> > https://codegolf.stackexchange.com/a/52902/2381
>
> Gag.
>
> Something I want to do for fun sometime is implement a 6809 emulator,
> then extend it to 32 bit math and addressing.
>
> Even just as recreation, implementing as perverse an architecture
> as the 8086 is not my definition of fun.
I understand and agree with this sentiment. I chose to do that one,
a. because it was there, already posted as a challenge; and b. "because
it is hard" (cf JFK's Moon Speech).
> Not that it would be hard. It would not be hard. But plenty of
> emulators already exist. If I really want to remember the bad
> old days, I can use one of those. 8-9
>
> > Another unsolicited tip I received many years ago and am still
> > learning to follow is:
> >
> > Break it up into small functions.
>
> Funny thing about that.
>
> > Super small functions. There's a saying that there are 2 ways to
> > design a system:
> >
> > 1. make it so simple that there are obviously no deficiencies
> > 2. make it so complication that there are no obvious deficiences
> >
> > Small functions give you the first choice. A 2- or 3- line function
> > with a good name can be easily scanned and verified so the brain
> > can move on to the next task.
>
> You probably really like Forth, then.
I do. I don't feel I have a real handle on it, though. Several times
I've gotten a few chapters into Brodie and got bored. Perhaps my
motives are wrong. Since I'm never trying to learn Forth in order
to /do/ Forth programming, but to steal ideas, I never seem to
completely enter the headspace. Same difficulty with Lisp.
I posted in comp.lang.forth to announce myself as a lurker:
https://groups.google.com/d/topic/comp.lang.forth/rIVqivnKX3Q/discussion
And I'm definitely a fan of PostScript which lots of people say is like
Forth (IME they really bear few similarities). In theory PS should be
like an "Object Forth" but brief investigation has not substantiated that
claim either.
> I suppose you must not have ventured into the files with the
> primitives. Or maybe you just saw the harder primitives. (Some
> things just really cannot be done in two or three lines of
> code.)
>
> The start-up code needs to be thoroughly refactored, and it
> really could benefit from using the vm itself, but I was in a
> hurry when I wrote that and had been writing mostly Java at
> the time. Shifting gears was a bit too much trouble. If I can
> ever make time, I should fix it.
>
> There are some subtle bugs in my start-up code, and if I use a
> bit less cryptic technique for the standard I/O redirection, I
> might be able to get it to compile something that runs on Android.
>
> > Hope some of this is helpful, albeit not very targeted. I really
> > tried digging into your code, but I started drowning before I got
> > very deep. I have a sense that a lot of the hardware details [are]
> > unnecessary and causing a great deal of extra complexity. But I may
> > be mistaken, as admittedly I did not grok through very far.
>
> Enjoyed reading your code. Sorry to have subjected you to such a
> mess.
>
No problem, thanks for the word back.
If I see the links again, I'll probably click again.
So keep the group updated with your progress (and questions). :)
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2017-04-27 10:46 -0400 |
| Message-ID | <odt02g$k55$1@dont-email.me> |
| In reply to | #108589 |
On 04/27/2017 06:13 AM, joel.rees@gmail.com wrote:
> ----------------
> unsigned byteWidth = 8; /* Not depending on limits.h . */
> unsigned byteMask = 0xFF;
> unsigned ulBytes = 4; /* Sane throw-away initial values. */
>
> void setULbytes( void )
> { int i = 0;
> unsigned char chroller = 1;
> unsigned char chMask = 1;
> unsigned long ulroller = 1;
> while ( chroller != 0 )
> { chroller <<= 1;
> chMask = ( chMask << 1 ) | 1;
> ++i;
> }
> byteMask = chMask;
> byteWidth = i;
> i = 0;
> while ( ulroller != 0 )
> { ulroller <<= 1;
> ++i;
> }
> ulBytes = i / byteWidth;
> }
> ----------------
>
> Yes, there is a reason I am ignoring limits.h. Maybe not a good
> reason, but I will debate that later.
>
> Right now I just would like to hear whether shifting unsigned values
> until the bits are supposed to disappear, and testing them for zero,
For unsigned types, the behavior of such shifts are well defined. The
disappearance of bits that you refer to is described in the standard
using the phrase "... reduced modulo one more than the maximum value
representable in the result type." (6.7.4p4)
So long as UCHAR_MAX < INT_MAX, your unsigned char value will get
promoted to "int", which is a signed type. However, unless 2U*UCHAR_MAX
> INT_MAX, you won't run into trouble with this code, since you never
shift by more than 1 bit. If you want to avoid worrying about that
remote possibility, use unsigned int for all of the intermediate steps
in this process.
> is considered in the range of machine-defined stuff that the current
> crop of optimization sophomores (pardon my Latin) conflates with
> undefined.
Well, you don't have to be an optimization sophomore to understand
correctly that the behavior is undefined for signed types. All you have
to do is be able to read English. Later in the same paragraph it says
(about E1 << E2) that "If E1 has a signed type and nonnegative value,
and E1 × 2^E2 is representable in the result type, then that is the
resulting value; otherwise, the behavior is undefined."
Note that "machine-defined" is a meaningless concept in this context. A
machine might have an instruction that could be used to implement a
bit-wise shift, but an implementation of C targeting that machine is
under no obligation to translate a bit-wise shift instruction into that
instruction. When the behavior is well-defined, the implementation is
required to produce the specified behavior, but using that particular
machine instruction is not the only way that could be achieved. Sane
implementors will use some other method only if they think they have a
good reason for doing so. However, if they do think that, the standard
says nothing to prohibit them from doing so.
When the behavior is undefined, the standard, by definition, imposes no
obligations whatsoever on the implementation. In particular, the
implementation is not obligated to produce the same behavior that would
have occurred if it had used that particular machine instruction to
implement the shift. If there's any good reason for using any other way
of achieving the same result when the behavior is defined, that
alternative way has a good chance of NOT producing the same behavior
when the behavior is undefined.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-04-27 08:37 -0700 |
| Message-ID | <307ebff5-b74f-46ab-beb7-7e2e4ff494fb@googlegroups.com> |
| In reply to | #108604 |
On Thursday, April 27, 2017 at 9:46:49 AM UTC-5, James Kuyper wrote: > Well, you don't have to be an optimization sophomore to understand > correctly that the behavior is undefined for signed types. All you have > to do is be able to read English. Later in the same paragraph it says > (about E1 << E2) that "If E1 has a signed type and nonnegative value, > and E1 × 2^E2 is representable in the result type, then that is the > resulting value; otherwise, the behavior is undefined." The clear intention of the Standard is that on a sign-magnitude platform whose hardware may randomly catch fire if the left-shift instruction is fed a negative number, a compiler for such a platform would have no obligation to prevent that from happening. I see no evidence that the authors of the Standard expected or intended that implementations targeting two's-complement hardware would should not opt to behave "in a documented manner characteristic of the environment". The authors of C89 deliberately avoided defining behaviors that would be applicable to some machines but not others, figuring that compiler writers and programmers alike should be able to recognize the obvious useful cases. Incidentally, I'm curious about which standard-conforming C compiler for a two's-complement machine was the first one to perform an optimization by treating a left shift of a negative number as something other than repeated multiplication by two in cases where the latter would not overflow. I would guess it was this century, but it would be interesting to know precisely.
[toc] | [prev] | [next] | [standalone]
Page 6 of 7 — ← Prev page 1 2 3 4 5 [6] 7 Next page →
Back to top | Article view | comp.lang.c
csiph-web