Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #108589 > unrolled thread

Is this code considered to transgress the signed overflow purism?

Started byjoel.rees@gmail.com
First post2017-04-27 03:13 -0700
Last post2017-04-30 22:05 -0700
Articles 20 on this page of 127 — 21 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#109096

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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]


#109122

FromRobert Wessel <robertwessel2@yahoo.com>
Date2017-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]


#109126

FromKeith Thompson <kst-u@mib.org>
Date2017-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]


#109313

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-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]


#109099

FromThiago Adams <thiago.adams@gmail.com>
Date2017-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]


#109100

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2017-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]


#109102

FromThiago Adams <thiago.adams@gmail.com>
Date2017-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]


#109103

FromThiago Adams <thiago.adams@gmail.com>
Date2017-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]


#109110

Fromjadill33@gmail.com
Date2017-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]


#109059

Fromsupercat@casperkitty.com
Date2017-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]


#109152

Fromjoel.rees@gmail.com
Date2017-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]


#108812

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-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]


#108848

Fromjoel.rees@gmail.com
Date2017-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]


#109020

FromTim Rentsch <txr@alumni.caltech.edu>
Date2017-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]


#109156

Fromjoel.rees@gmail.com
Date2017-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]


#109563

Fromluser droog <luser.droog@gmail.com>
Date2017-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]


#109638

Fromjoel.rees@gmail.com
Date2017-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]


#109639

Fromluser droog <luser.droog@gmail.com>
Date2017-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]


#108604

FromJames Kuyper <jameskuyper@verizon.net>
Date2017-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]


#108608

Fromsupercat@casperkitty.com
Date2017-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