Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #10309 > unrolled thread
| Started by | jacob navia <jacob@spamsink.net> |
|---|---|
| First post | 2011-09-16 08:30 +0200 |
| Last post | 2011-09-22 06:59 -0700 |
| Articles | 20 on this page of 127 — 27 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Michael Press <rubrum@pacbell.net> |
|---|---|
| Date | 2011-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-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]
| From | "Tony" <nospamme@ever.net> |
|---|---|
| Date | 2011-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]
| From | ImpalerCore <jadill33@gmail.com> |
|---|---|
| Date | 2011-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]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2011-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]
| From | "Tony" <nospamme@ever.net> |
|---|---|
| Date | 2011-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-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]
| From | pete <pfiland@mindspring.com> |
|---|---|
| Date | 2011-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]
| From | "Tony" <nospamme@ever.net> |
|---|---|
| Date | 2011-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]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2011-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]
| From | "Tony" <nospamme@ever.net> |
|---|---|
| Date | 2011-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2011-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]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-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]
| From | "Tony" <nospamme@ever.net> |
|---|---|
| Date | 2011-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]
| From | HENRY Eshbaugh <henryeshbaugh@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-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]
| From | HENRY Eshbaugh <henryeshbaugh@gmail.com> |
|---|---|
| Date | 2011-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]
| From | "Tony" <nospamme@ever.net> |
|---|---|
| Date | 2011-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]
| From | Jonathan Leffler <jleffler@earthlink.net> |
|---|---|
| Date | 2011-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