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


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

Reversing a linked list

Started byjacob navia <jacob@spamsink.net>
First post2011-09-16 08:30 +0200
Last post2011-09-22 06:59 -0700
Articles 20 on this page of 127 — 27 participants

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


Contents

  Reversing a linked list jacob navia <jacob@spamsink.net> - 2011-09-16 08:30 +0200
    Re: Reversing a linked list jacob navia <jacob@spamsink.net> - 2011-09-16 08:33 +0200
    Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-16 12:51 +0100
      Re: Reversing a linked list jacob navia <jacob@spamsink.net> - 2011-09-16 14:18 +0200
        Re: Reversing a linked list jacob navia <jacob@spamsink.net> - 2011-09-16 14:26 +0200
          Re: Reversing a linked list Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-16 07:09 -0700
            Re: Reversing a linked list ImpalerCore <jadill33@gmail.com> - 2011-09-16 08:28 -0700
              Re: Reversing a linked list falk@rahul.net (Edward A. Falk) - 2011-09-16 16:34 +0000
              Re: Reversing a linked list Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-16 09:28 -0700
                Re: Reversing a linked list ImpalerCore <jadill33@gmail.com> - 2011-09-16 11:12 -0700
                  Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-16 20:01 -0500
        Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-16 21:56 +0100
          Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-16 20:16 -0500
            Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-17 02:48 +0100
              Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-16 22:15 -0500
                Re: Reversing a linked list jacob navia <jacob@spamsink.net> - 2011-09-17 07:40 +0200
                  Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-17 01:24 -0500
                  Re: Reversing a linked list cri@tiac.net (Richard Harter) - 2011-09-17 15:07 +0000
                    Re: Reversing a linked list jacob navia <jacob@spamsink.net> - 2011-09-17 17:47 +0200
                      Re: Reversing a linked list jacob navia <jacob@spamsink.net> - 2011-09-17 17:54 +0200
                    Re: Reversing a linked list Michael Press <rubrum@pacbell.net> - 2011-09-27 19:21 -0700
                Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-17 12:00 +0100
                  Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-17 23:53 -0500
      Re: Reversing a linked list ImpalerCore <jadill33@gmail.com> - 2011-09-16 07:21 -0700
        Re: Reversing a linked list jacob navia <jacob@spamsink.net> - 2011-09-16 16:47 +0200
          Re: Reversing a linked list Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-16 08:20 -0700
          Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-16 20:25 -0500
        Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-16 22:32 +0100
        Re: Reversing a linked list pete <pfiland@mindspring.com> - 2011-09-16 17:53 -0400
      Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-16 19:48 -0500
        Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-17 02:41 +0100
          Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-16 22:57 -0500
            Re: Reversing a linked list "BartC" <bc@freeuk.com> - 2011-09-17 12:48 +0100
              Re: Reversing a linked list jacob navia <jacob@spamsink.net> - 2011-09-17 13:55 +0200
              Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-17 23:39 -0500
    Re: Reversing a linked list HENRY Eshbaugh <henryeshbaugh@gmail.com> - 2011-09-16 16:56 -0700
      Re: Reversing a linked list Ian Collins <ian-news@hotmail.com> - 2011-09-17 12:09 +1200
        Re: Reversing a linked list HENRY Eshbaugh <henryeshbaugh@gmail.com> - 2011-09-16 19:53 -0700
          Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-16 23:00 -0500
            Re: Reversing a linked list Jonathan Leffler <jleffler@earthlink.net> - 2011-09-16 23:20 -0700
            Re: Reversing a linked list Keith Thompson <kst-u@mib.org> - 2011-09-17 13:46 -0700
              Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-17 19:51 -0700
                Re: Reversing a linked list Keith Thompson <kst-u@mib.org> - 2011-09-18 01:28 -0700
                  Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-18 15:39 -0700
                    Re: Reversing a linked list Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-18 22:43 +0000
                      Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-18 17:54 -0700
                        Re: Reversing a linked list James Kuyper <jameskuyper@verizon.net> - 2011-09-18 21:20 -0400
                    Re: Reversing a linked list Keith Thompson <kst-u@mib.org> - 2011-09-18 17:30 -0700
                      Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-18 17:51 -0700
                        Re: Reversing a linked list James Kuyper <jameskuyper@verizon.net> - 2011-09-18 21:34 -0400
                        Re: Reversing a linked list Robert Wessel <robertwessel2@yahoo.com> - 2011-09-18 21:25 -0500
                        Re: Reversing a linked list Keith Thompson <kst-u@mib.org> - 2011-09-19 09:56 -0700
                          Re: Reversing a linked list gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-19 17:16 +0000
                          Re: Reversing a linked list Willem <willem@toad.stack.nl> - 2011-09-19 17:25 +0000
                            Re: Reversing a linked list Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-19 23:40 -0700
                            Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-20 17:55 -0700
                          Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-20 17:48 -0700
                            Re: Reversing a linked list Geoff <geoff@invalid.invalid> - 2011-09-20 19:12 -0700
                              Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-21 10:15 -0700
                                Re: Reversing a linked list David Resnick <lndresnick@gmail.com> - 2011-09-22 08:43 -0700
                                  Re: Reversing a linked list Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-23 02:45 -0700
                                    Re: Reversing a linked list David Resnick <lndresnick@gmail.com> - 2011-09-23 05:38 -0700
                                      Re: Reversing a linked list Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-23 07:58 -0700
                                        Re: Reversing a linked list David Resnick <lndresnick@gmail.com> - 2011-09-23 08:15 -0700
                                          Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-23 18:00 +0100
                                            Re: Reversing a linked list David Resnick <lndresnick@gmail.com> - 2011-09-23 10:49 -0700
                                              Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-23 20:05 +0100
                                            Re: Reversing a linked list pete <pfiland@mindspring.com> - 2011-09-23 18:05 -0400
                                              Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 00:19 +0100
                                        Re: Reversing a linked list ImpalerCore <jadill33@gmail.com> - 2011-09-23 09:25 -0700
                                Re: Reversing a linked list Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-22 22:49 +0300
                            Re: Reversing a linked list Keith Thompson <kst-u@mib.org> - 2011-09-20 19:51 -0700
                              Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-21 09:51 -0700
                                Re: Reversing a linked list Keith Thompson <kst-u@mib.org> - 2011-09-21 11:21 -0700
                            Re: Reversing a linked list James Kuyper <jameskuyper@verizon.net> - 2011-09-20 23:00 -0400
                              Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-21 09:47 -0700
                                Re: Reversing a linked list Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-23 11:22 +0300
                                  Re: Reversing a linked list Keith Thompson <kst-u@mib.org> - 2011-09-23 08:20 -0700
                                    Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-23 18:12 +0100
                                      Re: Reversing a linked list Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 13:13 -0800
                                    Re: Reversing a linked list Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-23 23:49 +0300
                                      Re: Reversing a linked list James Kuyper <jameskuyper@verizon.net> - 2011-09-24 08:15 -0400
                                        Re: Reversing a linked list Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-24 20:15 +0300
                                      Re: Reversing a linked list Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 13:28 -0800
                                        Re: Reversing a linked list Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-02-12 01:41 +0200
                                          Re: Reversing a linked list Tim Rentsch <txr@alumni.caltech.edu> - 2012-03-08 09:08 -0800
                                            Re: Reversing a linked list Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-03-13 17:21 +0200
                              Re: Reversing a linked list Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 13:04 -0800
                            Re: Reversing a linked list Seebs <usenet-nospam@seebs.net> - 2011-09-23 01:46 +0000
                    Re: Reversing a linked list James Kuyper <jameskuyper@verizon.net> - 2011-09-18 21:17 -0400
              Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-17 23:50 -0500
                Re: Reversing a linked list Keith Thompson <kst-u@mib.org> - 2011-09-18 01:29 -0700
          Re: Reversing a linked list Seebs <usenet-nospam@seebs.net> - 2011-09-18 07:03 +0000
      Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-17 02:13 +0100
        Re: Reversing a linked list HENRY Eshbaugh <henryeshbaugh@gmail.com> - 2011-09-16 19:52 -0700
          Re: Reversing a linked list Willem <willem@toad.stack.nl> - 2011-09-17 08:58 +0000
            Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-18 15:32 -0700
              Re: Reversing a linked list James Kuyper <jameskuyper@verizon.net> - 2011-09-18 21:36 -0400
                Re: Reversing a linked list cri@tiac.net (Richard Harter) - 2011-09-19 05:24 +0000
                  Re: Reversing a linked list James Kuyper <jameskuyper@verizon.net> - 2011-09-19 08:21 -0400
                    Re: Reversing a linked list cri@tiac.net (Richard Harter) - 2011-09-19 14:28 +0000
                      Re: Reversing a linked list Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-19 17:01 +0100
                        Re: Reversing a linked list cri@tiac.net (Richard Harter) - 2011-09-19 16:25 +0000
                  Re: Reversing a linked list henry eshbaugh <henryeshbaugh@gmail.com> - 2011-09-21 10:41 -0700
                    Re: Reversing a linked list Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-21 17:58 +0000
                    Re: Reversing a linked list James Kuyper <jameskuyper@verizon.net> - 2011-09-21 14:07 -0400
                    Re: Reversing a linked list Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-21 11:15 -0700
                      Re: Reversing a linked list Keith Thompson <kst-u@mib.org> - 2011-09-21 11:37 -0700
                        Re: Reversing a linked list Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-23 11:50 +0300
                    Re: Reversing a linked list Seebs <usenet-nospam@seebs.net> - 2011-09-23 01:46 +0000
      Re: Reversing a linked list Geoff <geoff@invalid.invalid> - 2011-09-18 18:22 -0700
    Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-16 19:37 -0500
      Re: Reversing a linked list jacob navia <jacob@spamsink.net> - 2011-09-17 07:52 +0200
        Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-17 02:09 -0500
          Re: Reversing a linked list Ian Collins <ian-news@hotmail.com> - 2011-09-17 19:35 +1200
            Re: Reversing a linked list "Tony" <nospamme@ever.net> - 2011-09-17 03:35 -0500
          Programming languages jacob navia <jacob@spamsink.net> - 2011-09-17 22:14 +0200
            Re: Programming languages "Tony" <nospamme@ever.net> - 2011-09-18 00:11 -0500
              Re: Programming languages jacob navia <jacob@spamsink.net> - 2011-09-18 08:37 +0200
              Re: Programming languages Seebs <usenet-nospam@seebs.net> - 2011-09-18 07:03 +0000
                Re: Programming languages jacob navia <jacob@spamsink.net> - 2011-09-18 09:50 +0200
                Re: Programming languages Keith Thompson <kst-u@mib.org> - 2011-09-18 01:31 -0700
                  Re: Programming languages James Kuyper <jameskuyper@verizon.net> - 2011-09-18 06:43 -0400
                    Re: Programming languages Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-18 07:42 -0700
                  Re: Programming languages "Tony" <nospamme@ever.net> - 2011-09-18 04:05 -0500
              Re: Programming languages Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-18 07:40 -0700
    Re: Reversing a linked list Gene <gene.ressler@gmail.com> - 2011-09-22 06:59 -0700

Page 2 of 7 — ← Prev page 1 [2] 3 4 5 6 7  Next page →


#11035

FromMichael Press <rubrum@pacbell.net>
Date2011-09-27 19:21 -0700
Message-ID<rubrum-A4E968.19214127092011@news.albasani.net>
In reply to#10399
In article <4e74a735.162351176@text.giganews.com>,
 cri@tiac.net (Richard Harter) wrote:

> On Sat, 17 Sep 2011 07:40:54 +0200, jacob navia <jacob@spamsink.net>
> wrote:
> 
> >Le 17/09/11 05:15, Tony a écrit :
> >>>> Maybe at one time lack of argument checking could have been
> >>>> considered a "quality of implementation" issue, but today (and long
> >>>> has been) that is a difference between professional code and
> >>>> Programming 101 student
> >>>> code.
> >>>
> >Ben wrote:
> >
> >>> How do conclude, from what I said, that I am advocating a lack of due
> >>> diligence or not checking arguments?
> >>
> >And Tony answered:
> >> By suggesting that documentation can preclude doing argument checking,
> >> thereby "throwing the problem over the wall" making it the programmer's
> >> problem for not reading "the directions".
> >>
> >>
> >
> >Not all preconditions can be tested. For instance I proposed a routine
> >to test if a list is circular. It involves examining all the list.
> >
> >If a library (like the C Containers library) would do that, its
> >performance would be close to zero.
> 
> Well, no, it wouldn't.  The cost of checking whether a linked list
> terminates in a cycle is of the same order as the cost of reversing
> the list.  One could even integrate cycle checking into the reversal
> code.  If one does that one could also reverse a cycle terminated
> linked list by defining the new head as the node that joined the
> cycle.  I don't suppose you would want to do that but it could be done
> cheaply enough.

Here is the canonical linked list reversal.

struct ure
{
    struct ure *link;
    int         data;
};

struct ure *list_head = NULL;
    
    ...
 
    /* Build up the linked list. */

    ...

    {
        struct ure *tail;

        tail = list_head;
        list_head = NULL;
        for(; tail != NULL; tail = next)
        {
            struct ure *next;

            next = tail->link;
            tail->link = list_head;
            list_head = tail;
        }
    }

Given a linked list with a loop, this code terminates;
reversing the cycle, and leaving invariant the
transient and the node that has two nodes pointing at it.

list_head -> a -> b -> c -> d -> e -> c

list_head -> NULL                          | tail -> a -> b -> c -> d -> e -> c
list_head -> a -> NULL                     | tail -> b -> c -> d -> e -> c
list_head -> b -> a -> NULL                | tail -> c -> d -> e -> c
list_head -> c -> b -> a -> NULL           | tail -> d -> e -> c
list_head -> d -> c -> b -> a -> NULL      | tail -> e -> c
list_head -> e -> d -> c -> b -> a -> NULL | tail -> c
list_head -> c -> e -> d -> c              | tail -> b -> a -> NULL
list_head -> b -> c -> e -> d -> c         | tail -> a -> NULL
list_head -> a -> b -> c -> e -> d -> c    | tail -> NULL


We can analyze a linked list with a loop in O(1) space 
and O(n) time. This is done in three stages using two
separate variables to traverse the list: 

           Leader 
           Follower

In Stage 1 we need to test for a NULL that will show
that the linked list is NULL terminated, and prevent
dereferencing NULL.

Stage 1:
L <- list_head
F <- list_head
At each step F traverses one node, and L traverses two 
nodes. Eventually we have F = L, and F and L are
pointing at a node in the cycle.

Stage 2:
Save the value of L, then let L traverse nodes until L
is back at its saved value. Now we know the value of c,
the length of the cycle.

Stage 3:
L <- list_head
F <- list_head
Let L traverse c nodes. Now L and F step in tandem, one
node each for each step until L = F. Now L and F point
at the node that has two nodes pointing at it.

-- 
Michael Press

[toc] | [prev] | [next] | [standalone]


#10392

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-09-17 12:00 +0100
Message-ID<0.91127d58d13f68e3d738.20110917120026BST.874o0bwi0l.fsf@bsb.me.uk>
In reply to#10374
"Tony" <nospamme@ever.net> writes:

> Ben Bacarisse wrote:
>> "Tony" <nospamme@ever.net> writes:
>>
>>> Ben Bacarisse wrote:
>>>> jacob navia <jacob@spamsink.net> writes:
>>>> <snip>
>>>>> Concerning the "preconditions" term, Betrand Meyer uses it as one
>>>>> of the two parts of a function contract: The preconditions and the
>>>>> postconditions.
>>>>>
>>>>> The first ones are the ones that the function requires from its
>>>>> caller, and the second ones are the ones that the function
>>>>> ensures to its users. They are part of the Eiffel language that
>>>>> Meyer designed.
>>>>
>>>> Yes, I know a little about Eiffel.  My point it is that as soon as a
>>>> condition moves from being part of the caller's contract to part of
>>>> the function's responsibility,
>>>> it stops being a precondition; it
>>>> becomes part of the defined behaviour of the function.
>>>
>>> There is "precondition (tm)" as in Eiffel, and then there is the
>>> basic concept that existed way before Eiffel showed up. B. Meyer
>>> didn't invent the concepts, and the concepts are what is important,
>>> not the terminology. The responsibility for usage does not "move".
>>> Would you really want to use a library that didn't do its due
>>> diligence in argument checking? You may have made one of those
>>> "programmer error" things and maybe the code would still "work",
>>> i.e., not crash, but be erroneous and maybe you'd catch it elsewhere
>>> or maybe not.
>>> Maybe at one time lack of argument checking could have been
>>> considered a "quality of implementation" issue, but today (and long
>>> has been) that is a difference between professional code and
>>> Programming 101 student
>>> code.
>>
>> How do conclude, from what I said, that I am advocating a lack of due
>> diligence or not checking arguments?
>
> By suggesting that documentation can preclude doing argument checking, 
> thereby "throwing the problem over the wall" making it the programmer's 
> problem for not reading "the directions". 

I hope you now accept that that is not what I was saying.  In case there
is any doubt: I am not saying that.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#10423

From"Tony" <nospamme@ever.net>
Date2011-09-17 23:53 -0500
Message-ID<zPedq.293$CY4.129@newsfe04.iad>
In reply to#10392
Ben Bacarisse wrote:
> "Tony" <nospamme@ever.net> writes:
>
>> Ben Bacarisse wrote:
>>> "Tony" <nospamme@ever.net> writes:
>>>
>>>> Ben Bacarisse wrote:
>>>>> jacob navia <jacob@spamsink.net> writes:
>>>>> <snip>
>>>>>> Concerning the "preconditions" term, Betrand Meyer uses it as one
>>>>>> of the two parts of a function contract: The preconditions and
>>>>>> the postconditions.
>>>>>>
>>>>>> The first ones are the ones that the function requires from its
>>>>>> caller, and the second ones are the ones that the function
>>>>>> ensures to its users. They are part of the Eiffel language that
>>>>>> Meyer designed.
>>>>>
>>>>> Yes, I know a little about Eiffel.  My point it is that as soon
>>>>> as a condition moves from being part of the caller's contract to
>>>>> part of the function's responsibility,
>>>>> it stops being a precondition; it
>>>>> becomes part of the defined behaviour of the function.
>>>>
>>>> There is "precondition (tm)" as in Eiffel, and then there is the
>>>> basic concept that existed way before Eiffel showed up. B. Meyer
>>>> didn't invent the concepts, and the concepts are what is important,
>>>> not the terminology. The responsibility for usage does not "move".
>>>> Would you really want to use a library that didn't do its due
>>>> diligence in argument checking? You may have made one of those
>>>> "programmer error" things and maybe the code would still "work",
>>>> i.e., not crash, but be erroneous and maybe you'd catch it
>>>> elsewhere or maybe not.
>>>> Maybe at one time lack of argument checking could have been
>>>> considered a "quality of implementation" issue, but today (and long
>>>> has been) that is a difference between professional code and
>>>> Programming 101 student
>>>> code.
>>>
>>> How do conclude, from what I said, that I am advocating a lack of
>>> due diligence or not checking arguments?
>>
>> By suggesting that documentation can preclude doing argument
>> checking, thereby "throwing the problem over the wall" making it the
>> programmer's problem for not reading "the directions".
>
> I hope you now accept that that is not what I was saying.  In case
> there is any doubt: I am not saying that.

If that's "walking the line" and trying to suck me into your politics,

It's not going to ever happen, bitch. 

[toc] | [prev] | [next] | [standalone]


#10327

FromImpalerCore <jadill33@gmail.com>
Date2011-09-16 07:21 -0700
Message-ID<51096d0a-12c9-4eb2-9b85-cd42c2c79513@r21g2000yqr.googlegroups.com>
In reply to#10313
On Sep 16, 7:51 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> jacob navia <ja...@spamsink.net> writes:

[snip]

> > The first thing to do in a serious program is to check the validity of
> > the received arguments, i.e. test the preconditions as Bertrand Meyer
> > would say it. We test that the list handed to us is not Null (lines
> > 5-8) and that the list is not read-only (lines 9-12) since we are
> > going to modify it.
>
> This is not what I understand by the phrase "function precondition".
> Maybe Meyer uses it that way but I would be surprised.  Almost by
> definition, a precondition is something that you *don't* check.  It is
> stated in the documentation (and probably as a comment) but as soon as
> you test for it it becomes part of the defined behaviour of the function
> and stops being a precondition.  You can (often during development) use
> something like assert to make sure that your callers are keeping to the
> implied contract of the preconditions, but as soon as this check turns
> into "when l == NULL return error number XYZ" it stops being (at least
> by my understanding of the term) a precondition.

From my perspective, a precondition for a function is independent of
the method used to handle its violations.  This is what contrasts the
defensive programming from the design by contract paradigm.  They both
see the same function preconditions; they respond to them differently.

Take 'size_t strlen( const char* str )' for example.

\code
size_t strlen( const char* str )
{
  const char* s;

  for ( s = str; *s != '\0'; ++s )
    ;

  return s - str;
}
\endcode

If I were to list the preconditions, I would say that 'str' must
reference a character buffer and that buffer contain a terminating
'\0' character.  Some of these preconditions are testable, others are
not (when a memory debugger is not present).  It is difficult to
impossible to verify whether a fixed-width buffer passed to strlen
contains a '\0' without potentially generating a memory access
violation.

The de-facto error-handling method of much of the standard library is
to do nothing, which in my opinion blends the precondition with its
implicit response (nothing) to a precondition violation.  In other
languages like C++ or Eiffel, the response to precondition violations
may result an exception, or violate some explicit contract.

The point is that I believe it's a faulty view to combine a function's
preconditions with how the module responds to them.  For example, I
see GLib's abundant use of g_return_if_fail macros as a defensive
programming response to function preconditions.

\code
size_t strlen( const char* str )
{
  const char* s;

  g_return_val_if_fail( str != NULL, 0 );

  for ( s = str; *s != '\0'; ++s )
    ;

  return s - str;
}
\endcode

The 'assert' function is more like the design by contract approach by
responding to a precondition violation by aborting the program.

size_t strlen( const char* str )
{
  const char* s;

  assert( str != NULL );

  for ( s = str; *s != '\0'; ++s )
    ;

  return s - str;
}
\endcode

Best regards,
John D.

[snip]

[toc] | [prev] | [next] | [standalone]


#10328

Fromjacob navia <jacob@spamsink.net>
Date2011-09-16 16:47 +0200
Message-ID<j4vnhd$nrf$1@speranza.aioe.org>
In reply to#10327
Le 16/09/11 16:21, ImpalerCore a écrit :
>  From my perspective, a precondition for a function is independent of
> the method used to handle its violations.  This is what contrasts the
> defensive programming from the design by contract paradigm.  They both
> see the same function preconditions; they respond to them differently.
>

I would agree with that. For instance, "Reverse" needs a list with no
cycles.

It would be hugely expensive to test this precondition (I gave the code
for the test in an answer to Ben) since implies going through all the
list. But you are right that all the preconditions should be explicitely
documented, even if untested in the code.

The other precondition is that the list must be terminated by a NULL
pointer and all the Next pointer must be valid.

The first part can be easily tested with:

if (l->count > 0) assert(l->Last->Next == NULL);

This is cheap to do because the header structure stores a pointer
to the last element. But if there is no pointer to the last element
we have to go through the whole list, what makes testing for that
precondition extremely expensive.

I will add a commentary with this content to the preconditions
part.

Thanks for your input.

[toc] | [prev] | [next] | [standalone]


#10331

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2011-09-16 08:20 -0700
Message-ID<bce6c287-bffa-41ba-bda4-b9a0a5ca0da4@m5g2000vbm.googlegroups.com>
In reply to#10328
On Sep 16, 5:47 pm, jacob navia <ja...@spamsink.net> wrote:
> But you are right that all the preconditions should be explicitely
> documented, even if untested in the code.
>
Depends on the audience. For a proposed standard library, I agree.
However in client code you can expect users to understand that linked
lists will be NULL-terminated and cycle free. There is a problem with
null pointers, which may be used to represent either the empty list or
an invalid list.
--
Read my review of Atlas Shrugged
http://www.malcolmmclean.site11.com/www




[toc] | [prev] | [next] | [standalone]


#10369

From"Tony" <nospamme@ever.net>
Date2011-09-16 20:25 -0500
Message-ID<TFScq.9153$Rq3.912@newsfe13.iad>
In reply to#10328
jacob navia wrote:
> Le 16/09/11 16:21, ImpalerCore a écrit :
>>  From my perspective, a precondition for a function is independent of
>> the method used to handle its violations.  This is what contrasts the
>> defensive programming from the design by contract paradigm.  They
>> both see the same function preconditions; they respond to them
>> differently.
>
> I would agree with that. For instance, "Reverse" needs a list with no
> cycles.
>
> It would be hugely expensive to test this precondition (I gave the
> code for the test in an answer to Ben) since implies going through
> all the list. But you are right that all the preconditions should be
> explicitely documented, even if untested in the code.
>
> The other precondition is that the list must be terminated by a NULL
> pointer and all the Next pointer must be valid.
>
> The first part can be easily tested with:
>
> if (l->count > 0) assert(l->Last->Next == NULL);

That is an example of an invariant rather than a precondition.

>
> This is cheap to do because the header structure stores a pointer
> to the last element. But if there is no pointer to the last element
> we have to go through the whole list, what makes testing for that
> precondition extremely expensive.

It can be expensive though because that would only be active during 
development of the data structure. After the development of the data 
structure is completed, that can be removed (remove #define 
CHECK_INVARIANTS) for the data structure should be designed to guarantee 
that. In this case, the invariant check is a data structure development 
aid, nothing more.


[toc] | [prev] | [next] | [standalone]


#10352

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-09-16 22:32 +0100
Message-ID<0.3d7a98b17a7862e93809.20110916223257BST.87vcssw4ty.fsf@bsb.me.uk>
In reply to#10327
ImpalerCore <jadill33@gmail.com> writes:

> On Sep 16, 7:51 am, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>> jacob navia <ja...@spamsink.net> writes:
>
> [snip]
>
>> > The first thing to do in a serious program is to check the validity of
>> > the received arguments, i.e. test the preconditions as Bertrand Meyer
>> > would say it. We test that the list handed to us is not Null (lines
>> > 5-8) and that the list is not read-only (lines 9-12) since we are
>> > going to modify it.
>>
>> This is not what I understand by the phrase "function precondition".
>> Maybe Meyer uses it that way but I would be surprised.  Almost by
>> definition, a precondition is something that you *don't* check.  It is
>> stated in the documentation (and probably as a comment) but as soon as
>> you test for it it becomes part of the defined behaviour of the function
>> and stops being a precondition.  You can (often during development) use
>> something like assert to make sure that your callers are keeping to the
>> implied contract of the preconditions, but as soon as this check turns
>> into "when l == NULL return error number XYZ" it stops being (at least
>> by my understanding of the term) a precondition.
>
> From my perspective, a precondition for a function is independent of
> the method used to handle its violations.  This is what contrasts the
> defensive programming from the design by contract paradigm.  They both
> see the same function preconditions; they respond to them differently.

That's fair.  I was going to say that there is a grey area depending on
how the condition is handled but then I had trouble wording it and cut
it all -- all bar the part about assert.  You've put it well.  Some
things are tested which don't form don't form part of the specified
behaviour of the function yet are not tested for in an all-or-nothing
manner of an assert.

I still prefer to keep the term pre-condition for the contractual notion
of "what must be", even if some implementations of a function test for
some parts if it.  One trouble with Jacob's notion of testing some
conditions and calling that establishing pre-conditions it that it
suggests that what is tested is the full set and it rarely is.

<snip good example>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#10354

Frompete <pfiland@mindspring.com>
Date2011-09-16 17:53 -0400
Message-ID<4E73C53F.1648@mindspring.com>
In reply to#10327
ImpalerCore wrote:
 
> From my perspective, a precondition for a function is independent of
> the method used to handle its violations.  This is what contrasts the
> defensive programming from the design by contract paradigm.  They both
> see the same function preconditions; they respond to them differently.
> 
> Take 'size_t strlen( const char* str )' for example.
> 
> \code
> size_t strlen( const char* str )
> {
>   const char* s;
> 
>   for ( s = str; *s != '\0'; ++s )
>     ;
> 
>   return s - str;
> }
> \endcode
> 
> If I were to list the preconditions, I would say that 'str' must
> reference a character buffer and that buffer contain a terminating
> '\0' character.  Some of these preconditions are testable, others are
> not (when a memory debugger is not present).  It is difficult to
> impossible to verify whether a fixed-width buffer passed to strlen
> contains a '\0' without potentially generating a memory access
> violation.

Also as a precondition, 
the length of the string to be measured by that version of strlen,
should not be greater than PTRDIFF_MAX.

-- 
pete

[toc] | [prev] | [next] | [standalone]


#10365

From"Tony" <nospamme@ever.net>
Date2011-09-16 19:48 -0500
Message-ID<S7Scq.15581$Ll3.1194@newsfe16.iad>
In reply to#10313
"Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message 
news:0.58bc9b9dbe16eaa00140.20110916125127BST.87sjnwyabk.fsf@bsb.me.uk...
> jacob navia <jacob@spamsink.net> writes:

>> The first thing to do in a serious program is to check the validity of
>> the received arguments, i.e. test the preconditions as Bertrand Meyer
>> would say it. We test that the list handed to us is not Null (lines
>> 5-8) and that the list is not read-only (lines 9-12) since we are
>> going to modify it.
>
> This is not what I understand by the phrase "function precondition".
> Maybe Meyer uses it that way but I would be surprised.  Almost by
> definition, a precondition is something that you *don't* check.

That would be living dangerously indeed. That kind of programming went 
out in the, er, well apparently it hasn't, for you are still doing that!

> It is
> stated in the documentation (and probably as a comment) but as soon as
> you test for it it becomes part of the defined behaviour of the 
> function
> and stops being a precondition.

No it doesn't. It just means that when someone violates the precondition, 
something controlled and defined happens rather than "anything can 
happen". All arguments to public functions need to be verified*.

*Their are techniques that can be used sometimes to ensure that arguments 
cannot be wrong and therefore need not be checked. Those functions are 
great when you find/create them and worth the effort looking for.

>  You can (often during development) use
> something like assert to make sure that your callers are keeping to the
> implied contract of the preconditions, but as soon as this check turns
> into "when l == NULL return error number XYZ" it stops being (at least
> by my understanding of the term) a precondition.

No. (I'm not referring to B. Meyer's definitions though, but rather my 
own).

>
> Since this is a teaching exercise,

Of questionable appropriateness in the NG. (Read, I questioned its 
appropriateness).

[toc] | [prev] | [next] | [standalone]


#10370

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2011-09-17 02:41 +0100
Message-ID<0.72f11a4a4a9c50671ed6.20110917024107BST.87fwjwvtcc.fsf@bsb.me.uk>
In reply to#10365
"Tony" <nospamme@ever.net> writes:

> "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message 
> news:0.58bc9b9dbe16eaa00140.20110916125127BST.87sjnwyabk.fsf@bsb.me.uk...
>> jacob navia <jacob@spamsink.net> writes:
>
>>> The first thing to do in a serious program is to check the validity of
>>> the received arguments, i.e. test the preconditions as Bertrand Meyer
>>> would say it. We test that the list handed to us is not Null (lines
>>> 5-8) and that the list is not read-only (lines 9-12) since we are
>>> going to modify it.
>>
>> This is not what I understand by the phrase "function precondition".
>> Maybe Meyer uses it that way but I would be surprised.  Almost by
>> definition, a precondition is something that you *don't* check.
>
> That would be living dangerously indeed. That kind of programming went 
> out in the, er, well apparently it hasn't, for you are still doing
> that!

I bet that you are doing it too.  Does your binary search function check
that the list is sorted?  How do you check that your sort function's
compare function does, in fact, induce a correct ordering?  To get more
on topic, how do you check, in C, that a function taking a pointer is
passed a valid one?  Or one that it points to enough data.  Or...

These things -- that a function assumes about it's parameters -- are
what I call pre-conditions.  I accept you may not like that term, but
these unchecked or uncheckable things need a name.  What do you call
them?

>> It is
>> stated in the documentation (and probably as a comment) but as soon as
>> you test for it it becomes part of the defined behaviour of the 
>> function
>> and stops being a precondition.
>
> No it doesn't. It just means that when someone violates the precondition, 
> something controlled and defined happens rather than "anything can 
> happen". All arguments to public functions need to be verified*.

Mostly I agree, though I think you must agree that this is (a) not
possible in all cases, and (b) often deliberately not done even when
possible due to cost.  My point was not "don't check you arguments" but
"those things you assume are pre-conditions; those that you check for
are part of the defined behaviour of the function" (though I accept
there is some grey here).

<snip>
>>  You can (often during development) use
>> something like assert to make sure that your callers are keeping to the
>> implied contract of the preconditions, but as soon as this check turns
>> into "when l == NULL return error number XYZ" it stops being (at least
>> by my understanding of the term) a precondition.
>
> No. (I'm not referring to B. Meyer's definitions though, but rather my 
> own).

OK.  I don't want to argue about definitions.  It's interesting that
this term is used in different ways.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#10375

From"Tony" <nospamme@ever.net>
Date2011-09-16 22:57 -0500
Message-ID<NUUcq.20402$YA4.12530@newsfe14.iad>
In reply to#10370
Ben Bacarisse wrote:
> "Tony" <nospamme@ever.net> writes:
>
>> "Ben Bacarisse" <ben.usenet@bsb.me.uk> wrote in message
>> news:0.58bc9b9dbe16eaa00140.20110916125127BST.87sjnwyabk.fsf@bsb.me.uk...
>>> jacob navia <jacob@spamsink.net> writes:
>>
>>>> The first thing to do in a serious program is to check the
>>>> validity of the received arguments, i.e. test the preconditions as
>>>> Bertrand Meyer would say it. We test that the list handed to us is
>>>> not Null (lines 5-8) and that the list is not read-only (lines
>>>> 9-12) since we are going to modify it.
>>>
>>> This is not what I understand by the phrase "function precondition".
>>> Maybe Meyer uses it that way but I would be surprised.  Almost by
>>> definition, a precondition is something that you *don't* check.
>>
>> That would be living dangerously indeed. That kind of programming
>> went out in the, er, well apparently it hasn't, for you are still
>> doing
>> that!
>
> I bet that you are doing it too.

I'll take that bet!

> Does your binary search function
> check that the list is sorted?

If in usage I did that, then it would be a bug. No need to move to a 
higher level of abstraction in this issue. The issue is simple argument 
checking in a simple case. Of course (!) the concepts should be applied 
at higher levels too, but there is no need to complicate the simple case 
(assumed for obvious reasons) in discussion.

>  How do you check that your sort
> function's compare function does, in fact, induce a correct ordering?
> To get more on topic, how do you check, in C, that a function taking
> a pointer is passed a valid one?  Or one that it points to enough
> data.  Or...

Again, that is at the program level and the concepts still apply, but 
stick to the simple case please and the topic at hand which is exactly 
that documentation cannot replace argument checking. Well it can, but 
that is "bad programming" and "worst practice".

>
> These things -- that a function assumes about it's parameters -- are
> what I call pre-conditions.  I accept you may not like that term, but
> these unchecked or uncheckable things need a name.  What do you call
> them?

Alright, if that is what you meant. "Preconditions" is fine for the 
those, if you want to use the term that way. I tend to think of 
"precondition" as something that can be checked within the callee. That 
you have to guarantee what you are talking about at the higher level, 
seems to indicate it needs another name (or so I would have it, and 
reserve "precondition" for the way I use it). "Guarantee" fits in there 
somewhere, surely, as in, "the program has guaranteed that the list is 
sorted by design". Instead of saying, "This library function call has the 
precondition that the list must be sorted.", say "The program must 
guarantee that the list is sorted". Violate a "precondition", then, and 
no problem, something well-defined will happen during development/testing 
to keep that bug out of the code. Violate a required guarantee though, 
and you're hosed.
At the higher level during development, the instrumentation must be in 
place to ensure that the required guarantees are indeed being designed 
against. There doesn't appear to be avenue for formality (like there is 
with argument precondition checking), other than the specification of 
required guarantees.

So, how about "required guarantees" (to answer your question)? (I just 
came up with it from the above thoughts).

>
>>> It is
>>> stated in the documentation (and probably as a comment) but as soon
>>> as you test for it it becomes part of the defined behaviour of the
>>> function
>>> and stops being a precondition.
>>
>> No it doesn't. It just means that when someone violates the
>> precondition, something controlled and defined happens rather than
>> "anything can happen". All arguments to public functions need to be
>> verified*.
>
> Mostly I agree, though I think you must agree that this is (a) not
> possible in all cases,

Not with your definition of "precondition". Though you must have said it 
rather generally for me to jump all over it. I.e., included the argument 
checking that CAN be done in what you wrote. Further, I don't think the 
Eiffel usage includes such in its concept of "precondition" (?) and 
weren't you alluding to that as some kind of litmus of "precondition" 
terminology definition?

> and (b) often deliberately not done even when
> possible due to cost.

No, that is not an option. I don't know what other people/groups/whatever 
are doing with that these days for I've been away from that for so long. 
But, yes, I can fathom that that may be being done somewhere. Now THAT is 
a quality issue and that would not only be low quality software, but an 
inadequate development capability/process/outfit/etc. You just can't 
shortcut this stuff and hope for the best. Any software is only as good 
as the "weakest link" within it. If it breaks in deployment, the plane 
won't go down, but if EVERYONE were to be doing that shitty of a job, it 
just might do exactly that!

>  My point was not "don't check you arguments"

I thought that your point was that specification of "preconditions" is 
adequate -- checking by the library, when it can do so, is optional.

> but "those things you assume are pre-conditions; those that you check
> for are part of the defined behaviour of the function" (though I
> accept there is some grey here).

Not really, IMO, because it's the error path, not the mainline. The 
behavior is the description of the error handling mechanism rather than 
the application-program-specific behavior. IOW, that's the behavior IN 
ALL the functions of the program upon error (or simply checking on 
non-error, of course). It's like an "aspect".

>
> <snip>
>>>  You can (often during development) use
>>> something like assert to make sure that your callers are keeping to
>>> the implied contract of the preconditions, but as soon as this
>>> check turns into "when l == NULL return error number XYZ" it stops
>>> being (at least by my understanding of the term) a precondition.
>>
>> No. (I'm not referring to B. Meyer's definitions though, but rather
>> my own).
>
> OK.  I don't want to argue about definitions.  It's interesting that
> this term is used in different ways.
>

To what I said above, I think my own definition is like Meyer's (I don't 
know his EXACTLY) and unlike yours. 

[toc] | [prev] | [next] | [standalone]


#10396

From"BartC" <bc@freeuk.com>
Date2011-09-17 12:48 +0100
Message-ID<j521ed$3br$1@dont-email.me>
In reply to#10375
"Tony" <nospamme@ever.net> wrote in message
news:NUUcq.20402$YA4.12530@newsfe14.iad...
> Ben Bacarisse wrote:


> Again, that is at the program level and the concepts still apply, but
> stick to the simple case please and the topic at hand which is exactly
> that documentation cannot replace argument checking. Well it can, but that
> is "bad programming" and "worst practice".

Documentation ensures that if anything goes wrong due to wrong inputs, then
it is the caller's fault. (In the same way that if a circuit doesn't work as
expected, you check that it is being driven according to spec.)

And there are many, many reasons why not every possible input can be
verified.

However I don't recall you posting any code showing us all how these things
should be done!

-- 
bartc 

[toc] | [prev] | [next] | [standalone]


#10398

Fromjacob navia <jacob@spamsink.net>
Date2011-09-17 13:55 +0200
Message-ID<j521qu$ofm$1@speranza.aioe.org>
In reply to#10396
Le 17/09/11 13:48, BartC a écrit :

> And there are many, many reasons why not every possible input can be
> verified.
>
> However I don't recall you posting any code showing us all how these things
> should be done!
>

Like, (for instance), verifying that you got a correct pointer pointing
to a correct object of the specified length.

[toc] | [prev] | [next] | [standalone]


#10421

From"Tony" <nospamme@ever.net>
Date2011-09-17 23:39 -0500
Message-ID<UBedq.9683$Ol1.830@newsfe07.iad>
In reply to#10396
BartC wrote:
> "Tony" <nospamme@ever.net> wrote in message
> news:NUUcq.20402$YA4.12530@newsfe14.iad...
>> Ben Bacarisse wrote:
>
>
>> Again, that is at the program level and the concepts still apply, but
>> stick to the simple case please and the topic at hand which is
>> exactly that documentation cannot replace argument checking. Well it
>> can, but that is "bad programming" and "worst practice".
>
> Documentation ensures

Welll when you write a book on that, maybe your theories will have some 
worth? I stop you mid sentence. "Documentation ensures"... what! I dare 
you! Make me!

[toc] | [prev] | [next] | [standalone]


#10361

FromHENRY Eshbaugh <henryeshbaugh@gmail.com>
Date2011-09-16 16:56 -0700
Message-ID<9db0146f-702d-4079-99e2-d4d796f201b9@h11g2000vbc.googlegroups.com>
In reply to#10309
On Sep 16, 2:30 am, jacob navia <ja...@spamsink.net> wrote:
> This group has lost many people. One of the reasons is that the
> newcomers just ask a question or two, and do not see discussions
> that try to explain code, teaching newcomers to the language how
> a program works.
>
> This is a second example (after hexdump.c) of commented code,
> i.e. explaining step by step how a relatively simple operation
> is done.
>
> Reversing a linked list
> -----------------------
> This is an evergreen of data structures programming. In most classes
> you will get an exercise like this:
>
> Exercise 7: Given a list "L" reverse it without moving its contents.
>
> The solution for this exercise is to go through the list, relinking the
> "Next" pointers in the inverse order, without touching any data that
> the list may hold. We will use the code of the C containers library and
> study how it is done.
>
> The library uses a simple structure "ListElement" whose definition runs
> like this:
>
> typedef struct _ListElement {
>      struct _ListElement *Next;
>      char Data[];
>
> } ListElement;
>
> We have a pointer to the next element of the list, and a chunk of data
> of unspecified length. This is the basic structure that will be used
> to hold the list data. Besides the list element we have a header of the
> list, containing several fields not relevant to the task of our reverse
> function. We will use only the following fields from that header:
>
> o RaiseError: Pointer to the error function.
> o First: The first element of the list.
> o count: The number of items in the list.
> o Last: A pointer to the last element of the list.
> o timestamp: A counter of the modifications done to the list.
>
> The interface of the reverse function is simple: it receives a list to
> reverse as input and returns an integer result code. A negative result
> means failure (with different negative numbers as error codes) and a
> positive number means success.
>
>    1 static int Reverse(List *l)
>    2 {
>    3     ListElement *Previous,*Current,*Next;
>    4
>
> The first thing to do in a serious program is to check the validity of
> the received arguments, i.e. test the preconditions as Bertrand Meyer
> would say it. We test that the list handed to us is not Null (lines
> 5-8) and that the list is not read-only (lines 9-12) since we are going
> to modify it.
>
> If anything is wrong we return an error code after calling the error
> function. Note that the error function is a field either in a global
> structure
> called iError (for interface Error) or is a field of the list itself. We
> use the global interface iError in the case that the list is\Null, or the
> list specific error function for the read only error. This is a powerful
> feature of C called function pointers that we will discuss in more detail
> later on.
>
>    5     if (l == NULL) {
>    6         iError.RaiseError("iList.Reverse",CONTAINER_ERROR_BADARG);
>    7         return CONTAINER_ERROR_BADARG;
>    8     }
>    9     if (l->Flags & CONTAINER_READONLY) {
>   10         l->RaiseError("iList.Reverse",CONTAINER_ERROR_READONLY);
>   11         return CONTAINER_ERROR_READONLY;
>   12     }
>
> Then, we test for special conditions, i.e. for degenerate cases.
> Obviously, reversing an empty list or a list with only one element is
> very easy: we have nothing to do. We test for that (line 13) and return
> success immediately if that is the case.
>
>   13     if (l->count < 2)
>   14         return 1;
>
> Now, we setup our loop. We start with the first element (that must
> exist since the list has more than one element, line 15). Since we are
> going to reverse the list, the first element will be the last and the
> last will be the first. We setup the last one immediately since we know
> it in line 16. And before we start there is no previous element so we
> set it to NULL.
>
>   15     Next = l->First;
>   16     l->Last = l->First;
>   17     Previous = NULL;
>
> Now we go through the whole list. We save the "Next" value, and advance
> it to the next element. Then, we set the value of the current element's
> pointer to the previous, i.e. our current will point to previous
> reversing the direction of the list.
>
>   18     while (Next) {
>   19         Current = Next;
>   20         Next = Next->Next;
>   21         Current->Next = Previous;
>   22         Previous = Current;
>   23     }
>
> OK, we are done. We have gone through the whole list reversing
> pointers, and we arrive at the cleanup. We should first establish our
> "First" pointer, then we should ensure that our last element has
> the Null marker, and that our list is marked as modified. We return a
> positive number meaning success.
>
>   24     l->First = Previous;
>   25     l->Last->Next = NULL;
>   26     l->timestamp++;
>   27     return 1;
>   28 }

A recursive function is a lot more readable, plus more elegant.

void reverse_list(ListElement *head)
{
        if (head == NULL) return;

        __reverse_list(head->next, head);

        return;
}

void __reverse_list(ListElement *next, ListElement *this)
{
        if (this == NULL) return;

        if (next->next) __reverse_list(next, next->next);

        next->next = this;
        return;
}

[toc] | [prev] | [next] | [standalone]


#10362

FromIan Collins <ian-news@hotmail.com>
Date2011-09-17 12:09 +1200
Message-ID<9di6qkFr5dU2@mid.individual.net>
In reply to#10361
On 09/17/11 11:56 AM, HENRY Eshbaugh wrote:
>
> A recursive function is a lot more readable, plus more elegant.
>
> void reverse_list(ListElement *head)
> {
>          if (head == NULL) return;
>
>          __reverse_list(head->next, head);

You shouldn't use names starting with a double underscore, they are 
reserved for the implementation.

>          return;
> }
>
> void __reverse_list(ListElement *next, ListElement *this)
> {
>          if (this == NULL) return;
>
>          if (next->next) __reverse_list(next, next->next);
>
>          next->next = this;
>          return;
> }


-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#10373

FromHENRY Eshbaugh <henryeshbaugh@gmail.com>
Date2011-09-16 19:53 -0700
Message-ID<25e5e08c-ab14-4404-aedf-81af8f05401d@hb5g2000vbb.googlegroups.com>
In reply to#10362
On Sep 16, 8:09 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> You shouldn't use names starting with a double underscore, they are
> reserved for the implementation.

If that's not the implementation of the algorithm, then what is it?

[toc] | [prev] | [next] | [standalone]


#10376

From"Tony" <nospamme@ever.net>
Date2011-09-16 23:00 -0500
Message-ID<xXUcq.7973$mA3.5987@newsfe19.iad>
In reply to#10373
HENRY Eshbaugh wrote:
> On Sep 16, 8:09 pm, Ian Collins <ian-n...@hotmail.com> wrote:
>> You shouldn't use names starting with a double underscore, they are
>> reserved for the implementation.
>
> If that's not the implementation of the algorithm, then what is it?

By "implementation", Ian meant "the compiler". That is what is typically 
understood as "the implementation". As in, "the implementation of the 
language".

(Aside: Isn't a single underscore suggested for use by libraries?). 

[toc] | [prev] | [next] | [standalone]


#10382

FromJonathan Leffler <jleffler@earthlink.net>
Date2011-09-16 23:20 -0700
Message-ID<I8ednQHcsdmooenTnZ2dnUVZ_r-dnZ2d@earthlink.com>
In reply to#10376
On 9/16/11 9:00 PM, Tony wrote:
> HENRY Eshbaugh wrote:
>> On Sep 16, 8:09 pm, Ian Collins<ian-n...@hotmail.com>  wrote:
>>> You shouldn't use names starting with a double underscore, they are
>>> reserved for the implementation.
>>
>> If that's not the implementation of the algorithm, then what is it?
>
> By "implementation", Ian meant "the compiler". That is what is typically
> understood as "the implementation". As in, "the implementation of the
> language".
>
> (Aside: Isn't a single underscore suggested for use by libraries?).

The C99 standard says:

§7.1.3 Reserved identifiers

Each header declares or defines all identifiers listed in its associated 
subclause, and optionally declares or defines identifiers listed in its 
associated future library directions subclause and identifiers which are 
always reserved either for any use or for use as file scope identifiers.

— All identifiers that begin with an underscore and either an uppercase 
letter or another underscore are always reserved for any use.

— All identifiers that begin with an underscore are always reserved for 
use as identifiers with file scope in both the ordinary and tag name spaces.

— Each macro name in any of the following subclauses (including the 
future library directions) is reserved for use as specified if any of 
its associated headers is included; unless explicitly stated otherwise 
(see 7.1.4).

— All identifiers with external linkage in any of the following 
subclauses (including the future library directions) are always reserved 
for use as identifiers with external linkage.154)

— Each identifier with file scope listed in any of the following 
subclauses (including the future library directions) is reserved for use 
as a macro name and as an identifier with file scope in the same name 
space if any of its associated headers is included.

No other identifiers are reserved. If the program declares or defines an 
identifier in a context in which it is reserved (other than as allowed 
by 7.1.4), or defines a reserved identifier as a macro name, the 
behavior is undefined.

154) The list of reserved identifiers with external linkage includes 
errno, math_errhandling, setjmp, and va_end.

[toc] | [prev] | [next] | [standalone]


Page 2 of 7 — ← Prev page 1 [2] 3 4 5 6 7  Next page →

Back to top | Article view | comp.lang.c


csiph-web