Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #10412 > unrolled thread
| Started by | jacob navia <jacob@spamsink.net> |
|---|---|
| First post | 2011-09-18 00:29 +0200 |
| Last post | 2011-09-20 00:22 -0700 |
| Articles | 20 on this page of 284 — 42 participants |
Back to article view | Back to comp.lang.c
Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-18 00:29 +0200
Re: Testing if a pointer is valid Harald van Dijk <truedfx@gmail.com> - 2011-09-17 15:38 -0700
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-18 00:57 +0200
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-18 16:30 +0000
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-18 19:25 +0200
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-19 07:53 +1200
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-18 20:00 +0000
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-19 08:23 +1200
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-18 20:32 +0000
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-18 23:28 +0000
Re: Testing if a pointer is valid blp@cs.stanford.edu (Ben Pfaff) - 2011-09-18 16:38 -0700
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-19 04:27 +0000
Re: Testing if a pointer is valid blp@cs.stanford.edu (Ben Pfaff) - 2011-09-18 21:48 -0700
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-19 05:38 +0000
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-19 09:14 +0200
Re: Testing if a pointer is valid "BartC" <bc@freeuk.com> - 2011-09-19 10:10 +0100
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-19 05:07 -0700
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-19 14:24 +0100
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-19 16:10 +0200
Re: Testing if a pointer is valid "BartC" <bc@freeuk.com> - 2011-09-19 16:50 +0100
Re: Testing if a pointer is valid Ben Pfaff <blp@cs.stanford.edu> - 2011-09-19 08:11 -0700
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-19 17:21 +0200
Re: Testing if a pointer is valid "BartC" <bc@freeuk.com> - 2011-09-19 16:27 +0100
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-19 10:14 -0700
Re: Testing if a pointer is valid "BartC" <bc@freeuk.com> - 2011-09-19 19:56 +0100
Re: Testing if a pointer is valid blp@cs.stanford.edu (Ben Pfaff) - 2011-09-19 13:20 -0700
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-20 18:31 +0300
Re: Testing if a pointer is valid "BartC" <bc@freeuk.com> - 2011-09-20 17:44 +0100
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-20 17:06 -0700
Re: Testing if a pointer is valid "BartC" <bc@freeuk.com> - 2011-09-21 01:37 +0100
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-22 22:03 +0300
Re: Testing if a pointer is valid Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-28 02:33 -0700
Re: Testing if a pointer is valid ImpalerCore <jadill33@gmail.com> - 2011-09-19 13:01 -0700
Re: Testing if a pointer is valid ImpalerCore <jadill33@gmail.com> - 2011-09-19 14:42 -0700
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-20 10:08 +1200
Re: Testing if a pointer is valid ImpalerCore <jadill33@gmail.com> - 2011-09-20 07:55 -0700
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-19 16:39 +0000
Re: Testing if a pointer is valid blp@cs.stanford.edu (Ben Pfaff) - 2011-09-19 09:48 -0700
Re: Testing if a pointer is valid ImpalerCore <jadill33@gmail.com> - 2011-09-19 12:49 -0700
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-19 22:45 +0200
Re: Testing if a pointer is valid ImpalerCore <jadill33@gmail.com> - 2011-09-19 14:02 -0700
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-19 07:14 +0000
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-19 16:13 +0000
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-19 17:36 +0000
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-19 20:09 +0000
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-19 20:36 +0200
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-20 08:05 +1200
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-19 20:18 +0000
Re: Testing if a pointer is valid Jorgen Grahn <grahn+nntp@snipabacken.se> - 2011-09-19 23:37 +0000
Re: Testing if a pointer is valid Kenneth Brody <kenbrody@spamcop.net> - 2011-09-21 12:23 -0400
Re: Testing if a pointer is valid Kenneth Brody <kenbrody@spamcop.net> - 2011-09-21 12:09 -0400
Re: Testing if a pointer is valid websnarf <websnarf@gmail.com> - 2011-09-26 22:01 -0700
Re: Testing if a pointer is valid Kenneth Brody <kenbrody@spamcop.net> - 2011-09-19 13:51 -0400
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-19 20:11 +0000
Re: Testing if a pointer is valid Nobody <nobody@nowhere.com> - 2011-09-19 22:21 +0100
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-20 00:05 +0000
Re: Testing if a pointer is valid Nobody <nobody@nowhere.com> - 2011-09-18 23:34 +0100
Re: Testing if a pointer is valid pacman@kosh.dhis.org (Alan Curry) - 2011-09-18 22:47 +0000
Re: Testing if a pointer is valid tom st denis <tom@iahu.ca> - 2011-09-19 04:50 -0700
Re: Testing if a pointer is valid Kenneth Brody <kenbrody@spamcop.net> - 2011-09-19 13:42 -0400
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-19 20:30 +0200
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-20 08:09 +1200
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-19 22:38 +0200
Re: Testing if a pointer is valid Ike Naar <ike@iceland.freeshell.org> - 2011-09-19 20:50 +0000
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-19 22:53 +0200
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-19 22:30 +0100
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-20 00:05 +0200
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-20 00:31 +0100
Re: Testing if a pointer is valid Ike Naar <ike@iceland.freeshell.org> - 2011-09-19 22:43 +0000
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-20 00:59 +0200
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-20 11:50 +1200
Re: Testing if a pointer is valid blp@cs.stanford.edu (Ben Pfaff) - 2011-09-19 19:03 -0700
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-20 14:11 +1200
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-19 21:49 -0700
Re: Testing if a pointer is valid Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-28 06:17 -0700
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-28 07:02 -0700
Re: Testing if a pointer is valid Ike Naar <ike@sverige.freeshell.org> - 2011-09-20 07:26 +0000
Re: Testing if a pointer is valid Kenneth Brody <kenbrody@spamcop.net> - 2011-09-21 12:31 -0400
Re: Testing if a pointer is valid Kenneth Brody <kenbrody@spamcop.net> - 2011-09-21 12:26 -0400
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-21 21:20 +0200
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-21 19:40 +0000
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-22 07:46 +1200
Re: Testing if a pointer is valid "Rosario Pulvirenti" <NoInUseno1Spam@non.usare.invalid> - 2011-09-22 07:38 +0200
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-20 09:05 +1200
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-20 07:16 +0000
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-20 09:50 +0200
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-20 10:38 +0000
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-20 04:29 -0700
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-20 12:04 +0000
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-20 05:25 -0700
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-20 16:49 +0000
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-22 22:35 +0300
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-23 07:59 +0000
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-23 12:33 +0300
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-23 12:23 +0000
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-23 17:34 +0300
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-23 17:08 +0000
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-23 06:49 -0400
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-23 12:20 +0000
Re: Testing if a pointer is valid Seebs <usenet-nospam@seebs.net> - 2011-09-26 22:59 +0000
Re: Testing if a pointer is valid Michael Press <rubrum@pacbell.net> - 2011-09-30 01:27 -0700
Re: Testing if a pointer is valid Willem <willem@toad.stack.nl> - 2011-09-30 08:38 +0000
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-10-04 12:40 +0000
Re: Testing if a pointer is valid Kenneth Brody <kenbrody@spamcop.net> - 2011-09-21 12:00 -0400
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-21 21:17 +0200
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-18 23:21 +0000
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-18 17:32 -0700
Re: Testing if a pointer is valid Joe Wright <joewwright@comcast.net> - 2011-09-18 23:10 -0400
Re: Testing if a pointer is valid gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-19 03:34 +0000
Re: Testing if a pointer is valid Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2011-09-18 22:32 -0600
Re: Testing if a pointer is valid gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-20 14:18 +0000
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-20 18:15 +0200
Re: Testing if a pointer is valid "BartC" <bc@freeuk.com> - 2011-09-20 17:49 +0100
Re: Testing if a pointer is valid Willem <willem@toad.stack.nl> - 2011-09-20 17:02 +0000
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-20 20:35 +0200
Re: Testing if a pointer is valid Ike Naar <ike@iceland.freeshell.org> - 2011-09-20 20:30 +0000
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-20 22:35 +0200
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-22 22:07 +0300
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-22 16:11 -0400
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-23 12:28 +0300
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-23 06:44 -0400
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-23 17:33 +0300
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-23 11:31 -0400
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-23 20:09 +0200
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-23 20:02 +0200
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-23 13:49 -0700
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-24 09:01 +1200
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-23 23:08 +0200
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-24 09:43 +1200
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-23 22:13 +0100
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-23 23:45 +0200
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 00:01 +0100
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-24 09:47 +1200
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-23 17:22 -0400
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-23 23:47 +0200
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-24 09:50 +1200
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-23 18:06 -0400
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-24 10:25 +1200
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-24 08:02 -0400
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-24 14:13 +0200
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 14:07 +0100
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-24 13:15 +0000
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 15:20 +0100
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-24 11:28 -0400
Re: Testing if a pointer is valid Willem <willem@toad.stack.nl> - 2011-09-24 15:45 +0000
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-24 20:07 +0300
Re: Testing if a pointer is valid Richard Damon <news.x.richarddamon@xoxy.net> - 2011-09-24 14:31 -0400
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-24 21:49 +0100
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-24 14:40 -0700
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-25 01:14 +0100
Re: Testing if a pointer is valid Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 13:44 -0800
Re: Testing if a pointer is valid Richard Damon <news.x.richarddamon@xoxy.net> - 2011-09-24 20:23 -0400
Re: Testing if a pointer is valid Willem <willem@toad.stack.nl> - 2011-09-24 18:44 +0000
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-25 07:04 -0400
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-24 17:30 +0000
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-24 12:34 -0700
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-25 01:00 -0700
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-25 21:30 +1300
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-25 05:08 -0700
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-26 08:39 +1300
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-24 20:04 +0300
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-23 17:09 -0400
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-23 23:43 +0200
Re: Testing if a pointer is valid Michael Press <rubrum@pacbell.net> - 2011-09-27 20:48 -0700
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-10-03 19:59 +0300
Re: Testing if a pointer is valid Michael Press <rubrum@pacbell.net> - 2011-10-03 17:32 -0700
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-24 13:53 +0100
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-20 21:18 +0100
Re: Testing if a pointer is valid Willem <willem@toad.stack.nl> - 2011-09-20 20:35 +0000
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-20 22:45 +0200
Re: Testing if a pointer is valid Willem <willem@toad.stack.nl> - 2011-09-21 08:09 +0000
Re: Testing if a pointer is valid Noob <root@127.0.0.1> - 2011-09-22 13:04 +0200
Re: Testing if a pointer is valid Robert Wessel <robertwessel2@yahoo.com> - 2011-09-22 11:38 -0500
Re: Testing if a pointer is valid Noob <root@127.0.0.1> - 2011-09-23 10:41 +0200
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-22 22:20 +0300
Re: Testing if a pointer is valid Willem <willem@toad.stack.nl> - 2011-09-22 22:15 +0000
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-23 12:30 +0300
Re: Testing if a pointer is valid Seebs <usenet-nospam@seebs.net> - 2011-09-26 22:59 +0000
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-27 02:06 +0100
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-27 03:39 +0000
Re: Testing if a pointer is valid "Rosario Pulvirenti" <NoInUseno1Spam@non.usare.invalid> - 2011-10-03 19:51 +0200
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-10-03 19:11 +0100
Re: Testing if a pointer is valid "Rosario Pulvirenti" <NoInUseno1Spam@non.usare.invalid> - 2011-10-04 16:20 +0200
Re: Testing if a pointer is valid China Blue Corn Chips <chine.bleu@yahoo.com> - 2011-10-04 08:11 -0700
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-10-04 12:19 -0400
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-27 13:56 +0300
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-27 13:13 +0100
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-27 12:08 +0300
Re: Testing if a pointer is valid Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-29 01:00 -0700
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-20 21:59 +0100
Re: Testing if a pointer is valid Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2011-09-22 22:08 +0300
Re: Testing if a pointer is valid Willem <willem@toad.stack.nl> - 2011-09-20 17:00 +0000
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-20 20:32 +0200
Re: Testing if a pointer is valid gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-20 18:53 +0000
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-20 22:55 +0200
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-20 21:50 +0100
Re: Testing if a pointer is valid gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-21 15:48 +0000
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-21 16:12 +0000
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-21 09:42 -0700
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-21 18:01 +0000
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-21 21:00 +0100
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-21 21:32 +0200
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-22 12:40 +0100
Re: Testing if a pointer is valid gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-22 13:00 +0000
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-22 14:54 +0100
Re: Testing if a pointer is valid gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-22 14:03 +0000
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-22 11:39 -0700
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-24 13:44 +0100
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-24 12:23 -0700
Re: Testing if a pointer is valid Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-29 04:52 -0700
Re: Testing if a pointer is valid Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-29 04:51 -0700
Re: Testing if a pointer is valid Willem <willem@toad.stack.nl> - 2011-09-20 19:32 +0000
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-20 22:48 +0200
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-20 17:29 -0400
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-20 23:45 +0200
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-21 10:35 -0400
Re: Testing if a pointer is valid Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-29 05:04 -0700
Re: Testing if a pointer is valid Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-29 04:54 -0700
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-20 17:19 -0700
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-21 23:26 +0200
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-21 14:35 -0700
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-22 00:09 +0200
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-21 19:08 -0400
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-21 05:25 +0000
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-20 21:11 +0100
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-20 23:01 +0200
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-21 03:11 -0700
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-21 12:16 +0200
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-21 03:23 -0700
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-21 20:44 +0100
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-21 22:53 +0200
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-21 23:08 -0400
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-21 21:14 -0700
Re: Testing if a pointer is valid James Kuyper <jameskuyper@verizon.net> - 2011-09-22 07:17 -0400
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-22 16:37 +0100
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-22 16:25 +0100
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-22 11:36 -0700
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-24 13:37 +0100
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-24 13:50 +0000
Re: Testing if a pointer is valid gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-24 14:47 +0000
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-24 20:43 +0100
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-24 20:26 +0100
Re: Testing if a pointer is valid Richard Damon <news.x.richarddamon@xoxy.net> - 2011-09-24 20:53 -0400
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-25 02:30 +0100
Re: Testing if a pointer is valid Richard Damon <news.x.richarddamon@xoxy.net> - 2011-09-24 22:24 -0400
Re: Testing if a pointer is valid Ben Bacarisse <ben.usenet@bsb.me.uk> - 2011-09-25 12:36 +0100
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-21 13:56 -0700
Re: Testing if a pointer is valid "Rosario Pulvirenti" <NoInUseno1Spam@non.usare.invalid> - 2011-09-22 07:38 +0200
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-22 02:06 -0700
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-22 15:24 +0100
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-22 11:35 -0700
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-24 13:25 +0100
Re: Testing if a pointer is valid Seebs <usenet-nospam@seebs.net> - 2011-09-26 22:59 +0000
Re: Testing if a pointer is valid Tim Rentsch <txr@alumni.caltech.edu> - 2012-01-24 13:30 -0800
Re: Testing if a pointer is valid Nobody <nobody@nowhere.com> - 2011-09-22 18:23 +0100
Re: Testing if a pointer is valid gazelle@shell.xmission.com (Kenny McCormack) - 2011-09-21 15:40 +0000
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-21 20:20 +0100
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-19 06:39 +0000
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-19 10:06 -0700
Re: Testing if a pointer is valid Kleuskes & Moos <kleuske@somewhere.else.net> - 2011-09-20 07:03 +0000
Re: Testing if a pointer is valid pete <pfiland@mindspring.com> - 2011-09-19 19:17 -0400
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-20 20:57 +0100
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-19 05:14 +0000
Re: Testing if a pointer is valid Ian Collins <ian-news@hotmail.com> - 2011-09-19 18:02 +1200
Re: Testing if a pointer is valid cri@tiac.net (Richard Harter) - 2011-09-19 06:18 +0000
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-19 17:50 +0200
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-19 20:45 +0200
Re: Testing if a pointer is valid Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-09-28 08:05 -0700
Re: Testing if a pointer is valid Keith Thompson <kst-u@mib.org> - 2011-09-28 09:14 -0700
Re: Testing if a pointer is valid Malcolm McLean <malcolm.mclean5@btinternet.com> - 2011-09-18 23:52 -0700
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-20 20:45 +0100
Re: Testing if a pointer is valid August Karlstrom <fusionfile@gmail.com> - 2011-09-20 23:35 +0200
Re: Testing if a pointer is valid Rui Maciel <rui.maciel@gmail.com> - 2011-09-21 19:53 +0100
Re: Testing if a pointer is valid "BartC" <bc@freeuk.com> - 2011-09-17 23:54 +0100
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-18 00:59 +0200
Re: Testing if a pointer is valid Heikki Kallasjoki <fis+usenet@zem.fi> - 2011-09-17 23:35 +0000
Re: Testing if a pointer is valid jacob navia <jacob@spamsink.net> - 2011-09-18 01:47 +0200
Re: Testing if a pointer is valid Geoff <geoff@invalid.invalid> - 2011-09-17 17:15 -0700
Re: Testing if a pointer is valid Максим Фомин <maxim@maxim-fomin.ru> - 2011-09-18 00:43 -0700
Re: Testing if a pointer is valid "Rosario Pulvirenti" <NoInUseno1Spam@non.usare.invalid> - 2011-09-18 10:34 +0200
Re: Testing if a pointer is valid "Rosario Pulvirenti" <NoInUseno1Spam@non.usare.invalid> - 2011-09-20 09:28 +0200
Re: Testing if a pointer is valid Ike Naar <ike@iceland.freeshell.org> - 2011-09-18 12:55 +0000
Re: Testing if a pointer is valid "Joel C. Salomon" <joelcsalomon@gmail.com> - 2011-09-19 10:29 -0400
Re: Testing if a pointer is valid China Blue Corn Chips <chine.bleu@yahoo.com> - 2011-09-20 00:22 -0700
Page 2 of 15 — ← Prev page 1 [2] 3 4 … 15 Next page →
| From | Ben Pfaff <blp@cs.stanford.edu> |
|---|---|
| Date | 2011-09-19 08:11 -0700 |
| Message-ID | <87zki0wos1.fsf@blp.benpfaff.org> |
| In reply to | #10475 |
cri@tiac.net (Richard Harter) writes:
> On Sun, 18 Sep 2011 21:48:36 -0700, blp@cs.stanford.edu (Ben Pfaff)
> wrote:
>
>>cri@tiac.net (Richard Harter) writes:
>>
>>> Mon ami, you miscomprehend. I did not claim nor do I suppose that I
>>> can determine whether every pointer is valid. That is not the issue.
>>> It is the viewpoint. Let me quote:
>>>
>>> That's the users responsibility, not one the author of the library
>>> should concern himself with. If the user passes crap to the
>>> library, a crash (or at least a SIGSEGV) is what's called for.
>>>
>>> The issue is: As a library author do you validate your input as best
>>> you can and provide a graceful response to input error - again as best
>>> as you can? Or do you, perhaps, take the view that if "the user
>>> passes crap" it is their lookout.
>>>
>>> If the library author takes the view that the onus is on the crap
>>> passing user and therefore doesn't have to care whether about
>>> validating input or about designing the library software to be robust.
>>> Given my druthers, I'd rather not use software written by such an
>>> author.
>>
>>Personally, I believe that the author of a library should
>>document his assumptions on the input to a library, including the
>>degree to which the library tolerates deviations. Usually, I
>>would rather carefully use a *fast* library that does not verify
>>its input, instead of a slower library that does. The former I
>>can transform into the latter with wrapper functions, if
>>necessary; the latter I'm stuck with.
>
> Fair enough, if those are your only choices. Quite often, however,
> the cost of verification is insignificant. Choosing the *fast*
> library could be a premature optimization. Now if I actually had two
> libraries that did the same thing *and* I was really really concerned
> with speed *and* I did performance measurements on both *and* there a
> measurable difference, then I might go with the one that doesn't
> verify its inputs. How often does that happen?
It's pretty easy to come up with examples of functions that are
trivial if you don't check the arguments and nontrivial if you
do. An excerpt from a library of mine is below. Each of these
functions is only one or two machine instructions when inlined.
If the functions were modified to check for null pointers and for
invalid pointers, then they would at least double in code size
(making them less suitable as inline functions) and presumably in
execution time also.
Elsewhere in this thread, Jacob Navia suggested using 64-bit
magic numbers to mark memory regions of a particular type. That
would also increase the size of this data structure by 40% with
the C implementation that I most commonly use. Perhaps not
fatal, but definitely significant.
/* A node in the range set. */
struct range_set_node
{
struct bt_node bt_node; /* Binary tree node. */
unsigned long int start; /* Start of region. */
unsigned long int end; /* One past end of region. */
};
/* Returns the position of the first 1-bit in NODE. */
static inline unsigned long int
range_set_node_get_start (const struct range_set_node *node)
{
return node->start;
}
/* Returns one past the position of the last 1-bit in NODE. */
static inline unsigned long int
range_set_node_get_end (const struct range_set_node *node)
{
return node->end;
}
/* Returns the number of contiguous 1-bits in NODE. */
static inline unsigned long int
range_set_node_get_width (const struct range_set_node *node)
{
return node->end - node->start;
}
--
Ben Pfaff
http://benpfaff.org
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-09-19 17:21 +0200 |
| Message-ID | <j57mmd$1s9$1@speranza.aioe.org> |
| In reply to | #10494 |
Le 19/09/11 17:11, Ben Pfaff a écrit : > > Elsewhere in this thread, Jacob Navia suggested using 64-bit > magic numbers to mark memory regions of a particular type. That > would also increase the size of this data structure by 40% with > the C implementation that I most commonly use. Perhaps not > fatal, but definitely significant. Yes, the magic number of 64 bits and a pointer checking allow you to ensure that at a critical interface ina critical application the pointer you receive is valid. I never suggested using that kind of overhead at each pointer and at each function call. Let's keep this discussion sane. In most cases you do not need pointer checking. In some situations under certain constraints of security and availability (or in a debug setting) you want to test pointers for validity. THEN in THOSE CASES you can combine pointer checking with a magic number of 64 bits to be very sure that the pointer is OK before using it. Obviously you wouldn't do it in all your code. The containers library for instance resisted till now the temptation to add a "type" field to it.I may be add it in a debug version but for the "production" version it doesn't use run time checking. The serializing interface does use it since mixing a file of a list and a file of a vector is a common error. That would (if not checked) always lead to a crash since the code assumes a certain file structure. By making the test of the type of file at the start of the processing I avoid a crash and give a meaningful error message to the user: he/she has passed a wrong file to the library.
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2011-09-19 16:27 +0100 |
| Message-ID | <j57nkp$flk$1@dont-email.me> |
| In reply to | #10494 |
"Ben Pfaff" <blp@cs.stanford.edu> wrote in message news:87zki0wos1.fsf@blp.benpfaff.org... > It's pretty easy to come up with examples of functions that are > trivial if you don't check the arguments and nontrivial if you > do. An excerpt from a library of mine is below. Each of these > functions is only one or two machine instructions when inlined. The body of these functions is so trivial that one wonders why they aren't written in-line anyway, or at least wrapped in a macro. In neither case would you consider checking the pointers, so why do so when in function form? They wouldn't need checking because it is assumed, in in-line code, that pointers are valid, or they have already been validated. if functions A(p) and B(p) both validate their pointer using magic numbers or whatever, what happens when A() calls B(p)? Two lots of validity checking will be done! Suppose there is a chain of such calls (with some recursive algorithm for example)? It seems this can get out of hand. When we have trusted pointers, we need a way of communicating the fact to library functions so that a program doesn't spend half it's time checking arguments for no purpose. Perhaps two sets of each function, one fast and one safe. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-09-19 10:14 -0700 |
| Message-ID | <lnmxe05ua8.fsf@nuthaus.mib.org> |
| In reply to | #10496 |
"BartC" <bc@freeuk.com> writes:
> "Ben Pfaff" <blp@cs.stanford.edu> wrote in message
> news:87zki0wos1.fsf@blp.benpfaff.org...
>
>> It's pretty easy to come up with examples of functions that are
>> trivial if you don't check the arguments and nontrivial if you
>> do. An excerpt from a library of mine is below. Each of these
>> functions is only one or two machine instructions when inlined.
>
> The body of these functions is so trivial that one wonders why they aren't
> written in-line anyway, or at least wrapped in a macro.
Writing them in-line would be more error-prone. Making them functions
lets you give each operation a name.
How would a macro be better than an inline function?
[...]
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2011-09-19 19:56 +0100 |
| Message-ID | <j5839u$3n0$1@dont-email.me> |
| In reply to | #10506 |
"Keith Thompson" <kst-u@mib.org> wrote in message news:lnmxe05ua8.fsf@nuthaus.mib.org... > "BartC" <bc@freeuk.com> writes: >> "Ben Pfaff" <blp@cs.stanford.edu> wrote in message >> news:87zki0wos1.fsf@blp.benpfaff.org... >> >>> It's pretty easy to come up with examples of functions that are >>> trivial if you don't check the arguments and nontrivial if you >>> do. An excerpt from a library of mine is below. Each of these >>> functions is only one or two machine instructions when inlined. >> >> The body of these functions is so trivial that one wonders why they >> aren't >> written in-line anyway, or at least wrapped in a macro. > > Writing them in-line would be more error-prone. Making them functions > lets you give each operation a name. > > How would a macro be better than an inline function? Looking at the original functions, they are just applying some abstraction/hiding, so are doing exactly what macros are for. Written as functions, they are not guaranteed to be inline. And some overzealous maintainer might come along and decide the pointer arguments need to be validated... -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | blp@cs.stanford.edu (Ben Pfaff) |
|---|---|
| Date | 2011-09-19 13:20 -0700 |
| Message-ID | <87d3ewthbf.fsf@blp.benpfaff.org> |
| In reply to | #10516 |
"BartC" <bc@freeuk.com> writes:
> "Keith Thompson" <kst-u@mib.org> wrote in message
> news:lnmxe05ua8.fsf@nuthaus.mib.org...
>> "BartC" <bc@freeuk.com> writes:
>>> "Ben Pfaff" <blp@cs.stanford.edu> wrote in message
>>> news:87zki0wos1.fsf@blp.benpfaff.org...
>>>
>>>> It's pretty easy to come up with examples of functions that are
>>>> trivial if you don't check the arguments and nontrivial if you
>>>> do. An excerpt from a library of mine is below. Each of these
>>>> functions is only one or two machine instructions when inlined.
>>>
>>> The body of these functions is so trivial that one wonders why they
>>> aren't
>>> written in-line anyway, or at least wrapped in a macro.
>>
>> Writing them in-line would be more error-prone. Making them functions
>> lets you give each operation a name.
>>
>> How would a macro be better than an inline function?
>
> Looking at the original functions, they are just applying some
> abstraction/hiding, so are doing exactly what macros are for.
I would not describe abstraction or hiding as one of the main
reasons for macros, so I'd not use macros in this case.
I don't think that the "get_width" function could be portably
defined as a macro without expanding the node expression twice.
One of the reasons that I defined these as functions is because I
wasn't sure at first that I was going to use this
representation. For example, I could have used start and width
instead of start and end, or I could have used a different
representation that only defined start and end implicitly.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-09-20 18:31 +0300 |
| Message-ID | <871uvb44da.fsf@bazspaz.fatphil.org> |
| In reply to | #10516 |
"BartC" <bc@freeuk.com> writes: > "Keith Thompson" <kst-u@mib.org> wrote in message > news:lnmxe05ua8.fsf@nuthaus.mib.org... > > "BartC" <bc@freeuk.com> writes: > >> "Ben Pfaff" <blp@cs.stanford.edu> wrote in message > >> news:87zki0wos1.fsf@blp.benpfaff.org... > >> > >>> It's pretty easy to come up with examples of functions that are > >>> trivial if you don't check the arguments and nontrivial if you > >>> do. An excerpt from a library of mine is below. Each of these > >>> functions is only one or two machine instructions when inlined. > >> > >> The body of these functions is so trivial that one wonders why they > >> aren't > >> written in-line anyway, or at least wrapped in a macro. > > > > Writing them in-line would be more error-prone. Making them functions > > lets you give each operation a name. > > > > How would a macro be better than an inline function? > > Looking at the original functions, they are just applying some > abstraction/hiding, so are doing exactly what macros are for. > > Written as functions, they are not guaranteed to be inline. And some > overzealous maintainer might come along and decide the pointer > arguments need to be validated... How would a macro be better defended against an overzealous maintainter than an inline function. Phil -- "Religion is what keeps the poor from murdering the rich." -- Napoleon
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2011-09-20 17:44 +0100 |
| Message-ID | <j5afue$a5o$1@dont-email.me> |
| In reply to | #10577 |
"Phil Carmody" <thefatphil_demunged@yahoo.co.uk> wrote in message news:871uvb44da.fsf@bazspaz.fatphil.org... > "BartC" <bc@freeuk.com> writes: >> Written as functions, they are not guaranteed to be inline. And some >> overzealous maintainer might come along and decide the pointer >> arguments need to be validated... > > How would a macro be better defended against an overzealous > maintainter than an inline function. Because he ought to know better. An isolated function could conceivably be called from anywhere. A macro will always be used in-line in a function where any 'inputs' might be expected to be already verified or trusted. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2011-09-20 17:06 -0700 |
| Message-ID | <ln62km69nw.fsf@nuthaus.mib.org> |
| In reply to | #10580 |
"BartC" <bc@freeuk.com> writes:
> "Phil Carmody" <thefatphil_demunged@yahoo.co.uk> wrote in message
> news:871uvb44da.fsf@bazspaz.fatphil.org...
>> "BartC" <bc@freeuk.com> writes:
>
>>> Written as functions, they are not guaranteed to be inline. And some
>>> overzealous maintainer might come along and decide the pointer
>>> arguments need to be validated...
>>
>> How would a macro be better defended against an overzealous
>> maintainter than an inline function.
>
> Because he ought to know better.
>
> An isolated function could conceivably be called from anywhere. A macro will
> always be used in-line in a function where any 'inputs' might be expected to
> be already verified or trusted.
Because macros are never defined in headers?
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2011-09-21 01:37 +0100 |
| Message-ID | <j5bblf$7e5$1@dont-email.me> |
| In reply to | #10616 |
"Keith Thompson" <kst-u@mib.org> wrote in message news:ln62km69nw.fsf@nuthaus.mib.org... > "BartC" <bc@freeuk.com> writes: >> "Phil Carmody" <thefatphil_demunged@yahoo.co.uk> wrote in message >> news:871uvb44da.fsf@bazspaz.fatphil.org... >>> How would a macro be better defended against an overzealous >>> maintainter than an inline function. >> >> Because he ought to know better. >> >> An isolated function could conceivably be called from anywhere. A macro >> will >> always be used in-line in a function where any 'inputs' might be expected >> to >> be already verified or trusted. > > Because macros are never defined in headers? I don't understand why that would make a difference. I'm just making a point that functions tend to be treated differently. For example, a function might be analogous to a checkpoint on the border of a country; you might well expect passport checks to be implemented. Whereas a macro is more like a checkpoint within a country: anyone passing through can be assumed to already have entitlement to be there, and therefore passport checks are less likely to be needed. -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2011-09-22 22:03 +0300 |
| Message-ID | <87vcsk2yd6.fsf@bazspaz.fatphil.org> |
| In reply to | #10580 |
"BartC" <bc@freeuk.com> writes: > "Phil Carmody" <thefatphil_demunged@yahoo.co.uk> wrote in message > news:871uvb44da.fsf@bazspaz.fatphil.org... > > "BartC" <bc@freeuk.com> writes: > > >> Written as functions, they are not guaranteed to be inline. And some > >> overzealous maintainer might come along and decide the pointer > >> arguments need to be validated... > > > > How would a macro be better defended against an overzealous > > maintainter than an inline function. > > Because he ought to know better. A true Scotsman might not. > An isolated function could conceivably be called from anywhere. A > macro will always be used in-line in a function where any 'inputs' > might be expected to be already verified or trusted. I do not share your suppositions. Phil -- "Religion is what keeps the poor from murdering the rich." -- Napoleon
[toc] | [prev] | [next] | [standalone]
| From | Nick Keighley <nick_keighley_nospam@hotmail.com> |
|---|---|
| Date | 2011-09-28 02:33 -0700 |
| Message-ID | <dfd3fadd-45d3-4cc8-8269-8e12c6a6a8d3@z12g2000yqz.googlegroups.com> |
| In reply to | #10516 |
On Sep 19, 7:56 pm, "BartC" <b...@freeuk.com> wrote: > "Keith Thompson" <ks...@mib.org> wrote in message > > news:lnmxe05ua8.fsf@nuthaus.mib.org... > > > > > > > "BartC" <b...@freeuk.com> writes: > >> "Ben Pfaff" <b...@cs.stanford.edu> wrote in message > >>news:87zki0wos1.fsf@blp.benpfaff.org... > > >>> It's pretty easy to come up with examples of functions that are > >>> trivial if you don't check the arguments and nontrivial if you > >>> do. An excerpt from a library of mine is below. Each of these > >>> functions is only one or two machine instructions when inlined. > > >> The body of these functions is so trivial that one wonders why they > >> aren't > >> written in-line anyway, or at least wrapped in a macro. > > > Writing them in-line would be more error-prone. Making them functions > > lets you give each operation a name. > > > How would a macro be better than an inline function? > > Looking at the original functions, they are just applying some > abstraction/hiding, so are doing exactly what macros are for. since when? > Written as functions, they are not guaranteed to be inline. And some > overzealous maintainer might come along and decide the pointer arguments > need to be validated... > > -- > Bartc- Hide quoted text - > > - Show quoted text -
[toc] | [prev] | [next] | [standalone]
| From | ImpalerCore <jadill33@gmail.com> |
|---|---|
| Date | 2011-09-19 13:01 -0700 |
| Message-ID | <3a87ce76-608c-43ca-a13e-43abb17be875@s20g2000yqh.googlegroups.com> |
| In reply to | #10506 |
On Sep 19, 1:14 pm, Keith Thompson <ks...@mib.org> wrote: > "BartC" <b...@freeuk.com> writes: > > "Ben Pfaff" <b...@cs.stanford.edu> wrote in message > >news:87zki0wos1.fsf@blp.benpfaff.org... > > >> It's pretty easy to come up with examples of functions that are > >> trivial if you don't check the arguments and nontrivial if you > >> do. An excerpt from a library of mine is below. Each of these > >> functions is only one or two machine instructions when inlined. > > > The body of these functions is so trivial that one wonders why they aren't > > written in-line anyway, or at least wrapped in a macro. > > Writing them in-line would be more error-prone. Making them functions > lets you give each operation a name. Right, encapsulating the operation as a function assigns a semantic name to an underlying operation. It is a textbook case of information hiding. The value of the routine is that if the internal structure name changes for any reason, the name change only needs to be done to the access routines, not everywhere in the code. It can provide more readability in the general case where you may find 'struct->what->does- >this->mean'. The compiler is typically clever enough in most cases to optimize the function call away. > How would a macro be better than an inline function? > > [...] I find a macro to be more beneficial when one wants compiler granularity to enable/disable the function. For access routines to a data structure, definitely not. Best regards, John D.
[toc] | [prev] | [next] | [standalone]
| From | ImpalerCore <jadill33@gmail.com> |
|---|---|
| Date | 2011-09-19 14:42 -0700 |
| Message-ID | <2c9058b4-4401-45e1-97e2-198799606ebd@h9g2000yqi.googlegroups.com> |
| In reply to | #10525 |
On Sep 19, 4:01 pm, ImpalerCore <jadil...@gmail.com> wrote:
> On Sep 19, 1:14 pm, Keith Thompson <ks...@mib.org> wrote:
>
> > "BartC" <b...@freeuk.com> writes:
> > > "Ben Pfaff" <b...@cs.stanford.edu> wrote in message
> > >news:87zki0wos1.fsf@blp.benpfaff.org...
>
> > >> It's pretty easy to come up with examples of functions that are
> > >> trivial if you don't check the arguments and nontrivial if you
> > >> do. An excerpt from a library of mine is below. Each of these
> > >> functions is only one or two machine instructions when inlined.
>
> > > The body of these functions is so trivial that one wonders why they aren't
> > > written in-line anyway, or at least wrapped in a macro.
>
> > Writing them in-line would be more error-prone. Making them functions
> > lets you give each operation a name.
>
> Right, encapsulating the operation as a function assigns a semantic
> name to an underlying operation. It is a textbook case of information
> hiding. The value of the routine is that if the internal structure
> name changes for any reason, the name change only needs to be done to
> the access routines, not everywhere in the code. It can provide more
> readability in the general case where you may find 'struct->what->does->this->mean'. The compiler is typically clever enough in most cases
>
> to optimize the function call away.
>
> > How would a macro be better than an inline function?
>
> > [...]
>
> I find a macro to be more beneficial when one wants compiler
> granularity to enable/disable the function. For access routines to a
> data structure, definitely not.
Actually, that's not entirely true. I use macros to access generic
containers with void* where the type information is passed on to
another function that uses 'sizeof (type)'.
\code snippet
void* gc_array_front( struct c_array* array )
{
void* p = NULL;
if ( array->size ) {
p = array->buffer;
}
return p;
}
#define c_array_front( array, type ) ( (type*)
(gc_array_front( (array) )) )
\end snippet
If I store the 'sizeof (type)' in the array structure itself, it's
possible to assert that the internal element size assigned when the
array was allocated matches the size of the type used in the access
function.
\code snippet
void* gc_array_front( struct c_array* array, size_t size )
{
void* p = NULL;
c_return_value_if_fail( array != NULL, NULL );
c_return_value_if_fail( size == array->element_size, NULL );
if ( array->size ) {
p = array->buffer;
}
return p;
}
#define c_array_front( array, type ) ( (type*)
(gc_array_front( (array), sizeof (type) )) )
\endcode
This can generate a constraint violation for c_array_front( ar, char )
if the original container array contains objects of type 'double', but
it cannot distinguish between invalid casting between 'int' and
'float' (if 'sizeof (int) == sizeof (float)').
It's a very special case though :-)
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-09-20 10:08 +1200 |
| Message-ID | <9dpsr2F76kU2@mid.individual.net> |
| In reply to | #10535 |
On 09/20/11 09:42 AM, ImpalerCore wrote:
> On Sep 19, 4:01 pm, ImpalerCore<jadil...@gmail.com> wrote:
>>
>> I find a macro to be more beneficial when one wants compiler
>> granularity to enable/disable the function. For access routines to a
>> data structure, definitely not.
>
> Actually, that's not entirely true. I use macros to access generic
> containers with void* where the type information is passed on to
> another function that uses 'sizeof (type)'.
>
> \code snippet
> void* gc_array_front( struct c_array* array )
> {
> void* p = NULL;
>
> if ( array->size ) {
> p = array->buffer;
> }
>
> return p;
> }
>
> #define c_array_front( array, type ) ( (type*)
> (gc_array_front( (array) )) )
> \end snippet
>
> If I store the 'sizeof (type)' in the array structure itself, it's
> possible to assert that the internal element size assigned when the
> array was allocated matches the size of the type used in the access
> function.
>
> \code snippet
> void* gc_array_front( struct c_array* array, size_t size )
> {
> void* p = NULL;
>
> c_return_value_if_fail( array != NULL, NULL );
> c_return_value_if_fail( size == array->element_size, NULL );
>
> if ( array->size ) {
> p = array->buffer;
> }
>
> return p;
> }
>
> #define c_array_front( array, type ) ( (type*)
> (gc_array_front( (array), sizeof (type) )) )
> \endcode
>
> This can generate a constraint violation for c_array_front( ar, char )
> if the original container array contains objects of type 'double', but
> it cannot distinguish between invalid casting between 'int' and
> 'float' (if 'sizeof (int) == sizeof (float)').
>
> It's a very special case though :-)
Sometimes somewhat disparagingly (but accurately) known as "poor man's
templates" :)
--
Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | ImpalerCore <jadill33@gmail.com> |
|---|---|
| Date | 2011-09-20 07:55 -0700 |
| Message-ID | <78dae63f-1cce-462b-8d6a-11fd0719ec12@w21g2000yql.googlegroups.com> |
| In reply to | #10537 |
On Sep 19, 6:08 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> On 09/20/11 09:42 AM, ImpalerCore wrote:
>
>
>
> > On Sep 19, 4:01 pm, ImpalerCore<jadil...@gmail.com> wrote:
>
> >> I find a macro to be more beneficial when one wants compiler
> >> granularity to enable/disable the function. For access routines to a
> >> data structure, definitely not.
>
> > Actually, that's not entirely true. I use macros to access generic
> > containers with void* where the type information is passed on to
> > another function that uses 'sizeof (type)'.
>
> > \code snippet
> > void* gc_array_front( struct c_array* array )
> > {
> > void* p = NULL;
>
> > if ( array->size ) {
> > p = array->buffer;
> > }
>
> > return p;
> > }
>
> > #define c_array_front( array, type ) ( (type*)
> > (gc_array_front( (array) )) )
> > \end snippet
>
> > If I store the 'sizeof (type)' in the array structure itself, it's
> > possible to assert that the internal element size assigned when the
> > array was allocated matches the size of the type used in the access
> > function.
>
> > \code snippet
> > void* gc_array_front( struct c_array* array, size_t size )
> > {
> > void* p = NULL;
>
> > c_return_value_if_fail( array != NULL, NULL );
> > c_return_value_if_fail( size == array->element_size, NULL );
>
> > if ( array->size ) {
> > p = array->buffer;
> > }
>
> > return p;
> > }
>
> > #define c_array_front( array, type ) ( (type*)
> > (gc_array_front( (array), sizeof (type) )) )
> > \endcode
>
> > This can generate a constraint violation for c_array_front( ar, char )
> > if the original container array contains objects of type 'double', but
> > it cannot distinguish between invalid casting between 'int' and
> > 'float' (if 'sizeof (int) == sizeof (float)').
>
> > It's a very special case though :-)
>
> Sometimes somewhat disparagingly (but accurately) known as "poor man's
> templates" :)
Yeah, but sometimes "poor man's templates" can be still pretty good,
at least in C. While the macro technique sure doesn't beat C++
templates with its compile-time type verification, you can still
abstract a lot of the container grunt work that you see over and over
again that doesn't depend on type. From my experiments, using a macro
API to abstract access to type information was miles better than
sprinkling manual type-casting of void* pointers. It allows one to
have an opportunity to do some semblance of type-checking.
For the auto-resizing array, you can provide some type checking since
the container is localized in a single struct. Using a macro, one can
do something like the following.
\code snippet
struct c_array* gc_array_alloc( size_t sz, size_t n, const char*
name )
{
struct c_array* array = NULL;
...
/* alloc and assign 'name' to 'typename' struct member */
}
void* gc_array_front( struct c_array* array, const char* name )
{
void* p = NULL;
c_return_value_if_fail( array != NULL, NULL );
c_return_value_if_fail( strcmp( name, array->typename ) == 0,
NULL );
if ( array->size ) {
p = array->buffer;
}
return p;
}
#define c_array_new( type, n ) \
(gc_array_alloc( sizeof (type), (n), #type ))
#define c_array_front( array, type ) \
( (type*)(gc_array_front( (array), #type )) )
\endcode
I found this kind of setup to be quite fragile and computationally
expensive. You can try to improve upon strcmp with a string
comparison that ignores spaces, but it still can't deal with
typedefs. For this reason, I settled on using 'sizeof' as a hack to
verify that the type argument matches the array's internal type (at
least in size).
If there was a compiler extension that assigned a unique id to a
compiler type (kind of like a compile-time typeid), and it handled
typedefs properly as well, one could architect low cost run-time type
checking constraints into the generic array interface fairly easily,
ideally solving most of the type-mismatch issues with 'void*'. It
might even be cheap enough to use it in distributed containers like
linked lists and trees, provided users would use a macro API instead
of manual casting.
Best regards,
John D.
[toc] | [prev] | [next] | [standalone]
| From | cri@tiac.net (Richard Harter) |
|---|---|
| Date | 2011-09-19 16:39 +0000 |
| Message-ID | <4e776fc9.344779104@text.giganews.com> |
| In reply to | #10494 |
On Mon, 19 Sep 2011 08:11:10 -0700, Ben Pfaff <blp@cs.stanford.edu> wrote: >cri@tiac.net (Richard Harter) writes: > >> On Sun, 18 Sep 2011 21:48:36 -0700, blp@cs.stanford.edu (Ben Pfaff) >> wrote: >> >>>cri@tiac.net (Richard Harter) writes: >>> >>>> Mon ami, you miscomprehend. I did not claim nor do I suppose that I >>>> can determine whether every pointer is valid. That is not the issue. >>>> It is the viewpoint. Let me quote: >>>> >>>> That's the users responsibility, not one the author of the library >>>> should concern himself with. If the user passes crap to the >>>> library, a crash (or at least a SIGSEGV) is what's called for. >>>> >>>> The issue is: As a library author do you validate your input as best >>>> you can and provide a graceful response to input error - again as best >>>> as you can? Or do you, perhaps, take the view that if "the user >>>> passes crap" it is their lookout. >>>> >>>> If the library author takes the view that the onus is on the crap >>>> passing user and therefore doesn't have to care whether about >>>> validating input or about designing the library software to be robust. >>>> Given my druthers, I'd rather not use software written by such an >>>> author. >>> >>>Personally, I believe that the author of a library should >>>document his assumptions on the input to a library, including the >>>degree to which the library tolerates deviations. Usually, I >>>would rather carefully use a *fast* library that does not verify >>>its input, instead of a slower library that does. The former I >>>can transform into the latter with wrapper functions, if >>>necessary; the latter I'm stuck with. >> >> Fair enough, if those are your only choices. Quite often, however, >> the cost of verification is insignificant. Choosing the *fast* >> library could be a premature optimization. Now if I actually had two >> libraries that did the same thing *and* I was really really concerned >> with speed *and* I did performance measurements on both *and* there a >> measurable difference, then I might go with the one that doesn't >> verify its inputs. How often does that happen? > >It's pretty easy to come up with examples of functions that are >trivial if you don't check the arguments and nontrivial if you >do. Of course. Was anyone proposing some iron clad rule that everyone must follow? Is common sense not on the table? [snip]
[toc] | [prev] | [next] | [standalone]
| From | blp@cs.stanford.edu (Ben Pfaff) |
|---|---|
| Date | 2011-09-19 09:48 -0700 |
| Message-ID | <87hb48tr4b.fsf@blp.benpfaff.org> |
| In reply to | #10502 |
cri@tiac.net (Richard Harter) writes: > On Mon, 19 Sep 2011 08:11:10 -0700, Ben Pfaff <blp@cs.stanford.edu> > wrote: > >>cri@tiac.net (Richard Harter) writes: >> >>> On Sun, 18 Sep 2011 21:48:36 -0700, blp@cs.stanford.edu (Ben Pfaff) >>> wrote: >>> >>>>cri@tiac.net (Richard Harter) writes: >>>> >>>>> Mon ami, you miscomprehend. I did not claim nor do I suppose that I >>>>> can determine whether every pointer is valid. That is not the issue. >>>>> It is the viewpoint. Let me quote: >>>>> >>>>> That's the users responsibility, not one the author of the library >>>>> should concern himself with. If the user passes crap to the >>>>> library, a crash (or at least a SIGSEGV) is what's called for. >>>>> >>>>> The issue is: As a library author do you validate your input as best >>>>> you can and provide a graceful response to input error - again as best >>>>> as you can? Or do you, perhaps, take the view that if "the user >>>>> passes crap" it is their lookout. >>>>> >>>>> If the library author takes the view that the onus is on the crap >>>>> passing user and therefore doesn't have to care whether about >>>>> validating input or about designing the library software to be robust. >>>>> Given my druthers, I'd rather not use software written by such an >>>>> author. >>>> >>>>Personally, I believe that the author of a library should >>>>document his assumptions on the input to a library, including the >>>>degree to which the library tolerates deviations. Usually, I >>>>would rather carefully use a *fast* library that does not verify >>>>its input, instead of a slower library that does. The former I >>>>can transform into the latter with wrapper functions, if >>>>necessary; the latter I'm stuck with. >>> >>> Fair enough, if those are your only choices. Quite often, however, >>> the cost of verification is insignificant. Choosing the *fast* >>> library could be a premature optimization. Now if I actually had two >>> libraries that did the same thing *and* I was really really concerned >>> with speed *and* I did performance measurements on both *and* there a >>> measurable difference, then I might go with the one that doesn't >>> verify its inputs. How often does that happen? >> >>It's pretty easy to come up with examples of functions that are >>trivial if you don't check the arguments and nontrivial if you >>do. > > Of course. Was anyone proposing some iron clad rule that everyone > must follow? Is common sense not on the table? I guess that common sense is on the table, based on your response. Your original statement was very broad and, to my mind, overreaching. Now that you've qualified it, it makes more sense. -- "Some people *are* arrogant, and others read the FAQ." --Chris Dollin
[toc] | [prev] | [next] | [standalone]
| From | ImpalerCore <jadill33@gmail.com> |
|---|---|
| Date | 2011-09-19 12:49 -0700 |
| Message-ID | <5353a182-c2f4-4ecc-8a69-5c4dcf4161ec@b10g2000vbz.googlegroups.com> |
| In reply to | #10494 |
On Sep 19, 11:11 am, Ben Pfaff <b...@cs.stanford.edu> wrote:
> c...@tiac.net (Richard Harter) writes:
> > On Sun, 18 Sep 2011 21:48:36 -0700, b...@cs.stanford.edu (Ben Pfaff)
> > wrote:
>
> >>c...@tiac.net (Richard Harter) writes:
>
> >>> Mon ami, you miscomprehend. I did not claim nor do I suppose that I
> >>> can determine whether every pointer is valid. That is not the issue.
> >>> It is the viewpoint. Let me quote:
>
> >>> That's the users responsibility, not one the author of the library
> >>> should concern himself with. If the user passes crap to the
> >>> library, a crash (or at least a SIGSEGV) is what's called for.
>
> >>> The issue is: As a library author do you validate your input as best
> >>> you can and provide a graceful response to input error - again as best
> >>> as you can? Or do you, perhaps, take the view that if "the user
> >>> passes crap" it is their lookout.
>
> >>> If the library author takes the view that the onus is on the crap
> >>> passing user and therefore doesn't have to care whether about
> >>> validating input or about designing the library software to be robust.
> >>> Given my druthers, I'd rather not use software written by such an
> >>> author.
>
> >>Personally, I believe that the author of a library should
> >>document his assumptions on the input to a library, including the
> >>degree to which the library tolerates deviations. Usually, I
> >>would rather carefully use a *fast* library that does not verify
> >>its input, instead of a slower library that does. The former I
> >>can transform into the latter with wrapper functions, if
> >>necessary; the latter I'm stuck with.
>
> > Fair enough, if those are your only choices. Quite often, however,
> > the cost of verification is insignificant. Choosing the *fast*
> > library could be a premature optimization. Now if I actually had two
> > libraries that did the same thing *and* I was really really concerned
> > with speed *and* I did performance measurements on both *and* there a
> > measurable difference, then I might go with the one that doesn't
> > verify its inputs. How often does that happen?
>
> It's pretty easy to come up with examples of functions that are
> trivial if you don't check the arguments and nontrivial if you
> do. An excerpt from a library of mine is below. Each of these
> functions is only one or two machine instructions when inlined.
> If the functions were modified to check for null pointers and for
> invalid pointers, then they would at least double in code size
> (making them less suitable as inline functions) and presumably in
> execution time also.
>
> Elsewhere in this thread, Jacob Navia suggested using 64-bit
> magic numbers to mark memory regions of a particular type. That
> would also increase the size of this data structure by 40% with
> the C implementation that I most commonly use. Perhaps not
> fatal, but definitely significant.
>
> /* A node in the range set. */
> struct range_set_node
> {
> struct bt_node bt_node; /* Binary tree node. */
> unsigned long int start; /* Start of region. */
> unsigned long int end; /* One past end of region. */
> };
>
> /* Returns the position of the first 1-bit in NODE. */
> static inline unsigned long int
> range_set_node_get_start (const struct range_set_node *node)
> {
> return node->start;
> }
>
> /* Returns one past the position of the last 1-bit in NODE. */
> static inline unsigned long int
> range_set_node_get_end (const struct range_set_node *node)
> {
> return node->end;
> }
>
> /* Returns the number of contiguous 1-bits in NODE. */
> static inline unsigned long int
> range_set_node_get_width (const struct range_set_node *node)
> {
> return node->end - node->start;
> }
The only pointer check I consider useful at the library level is
whether NULL pointers are semantically valid as arguments to function
parameters. In your functions defined above, passing a NULL pointer
in as 'node' will introduce a memory access violation. One could
consider inserting a check at the module (library) level to verify
that the pointer argument is semantically valid.
\code
/* Returns the position of the first 1-bit in NODE. */
static inline unsigned long int
range_set_node_get_start (const struct range_set_node *node)
{
check_pointer_semantics (node != NULL);
return node->start;
}
\endcode
Unfortunately, when one wants to insert checking at the library level,
they enforce behavior on the client that is not satisfactory in all
scenarios. In development and debugging, 'check_pointer_semantics'
would prefer an assert like function. In production, crashing the
application due to passing a NULL pointer argument in
'range_set_node_get_start' may not be the preferred option. It might
be nice to save the current program's progress if it's a long
algorithm, or perhaps inform the user in a nicer fashion.
The best option I can come up with is to try to abstract the outcome
of a precondition violation. The check of a precondition can be split
into three phases: detection, reporting, and response. The detection
is evaluation of the precondition expression 'node != NULL'. The
reporting step may be a display of the file and line of the error like
'Precondition violation: node != NULL, file lib_source.c, line 123'.
The response can be to abort like 'assert', or to early-return with a
error value, or invoke a global procedure to save and shutdown, or pop
a dialog with an option to report the error. The standard library
'assert' can be represented as a combination of the three phases,
where the report is to print file and line information, and the
response is to 'abort'. The advantage is that when the constraint is
enforced at the library level, every call to
'range_set_node_get_start' is validated irregardless of the knowledge
and competency of the developers calling it.
The key to acceptance is providing an architecture that allows the
client (the application developer using the module) to sculpt the
report and response to these precondition violations in a manner that
is convenient. To help satisfy these requirements, I use macros that
reference a global function table that contains function pointers to
'report' and 'response' functions.
\code snippet
static struct c_constraint_violation_ftable
gc_private_constraint_violation_ftable =
{
gc_default_report_handler,
NULL
};
void c_constraint_violation_set_report_handler( void (*report_fn)
( const char*, const char*, int ) );
void c_constraint_violation_set_response_handler( void (*response_fn)
( void ) );
\endcode
The report handler 'gc_default_report_handler' would look like the
following.
\code snippet
void gc_default_report_handler( const char* expr, const char* file,
int line )
{
fprintf( stderr, "%s, file %s, line %d\n", expr, file, line );
fflush( stderr );
}
\endcode
The response and report handlers are called from a generic constraint
violation handler.
\code
void gc_constraint_violation( const char* expr, const char* file, int
line )
{
if ( gc_private_constraint_violation_ftable.report ) {
(*gc_private_constraint_violation_ftable.report)( expr, file,
line );
}
if ( gc_private_constraint_violation_ftable.response ) {
(*gc_private_constraint_violation_ftable.response)();
}
}
\endcode
Finally, I have a macros to evaluate the constraint and add any
additional response that cannot be encapsulated in the 'response'
function pointer.
\code snippet
#define c_return_value_if_fail( expr, val ) \
do \
{ \
if ( expr ) {} \
else \
{ \
g_constraint_violation( "Constraint violation: " #expr, \
__FILE__, __LINE__ ); \
return (val); \
} \
} while (0)
\endcode
There is also a 'c_return_if_fail' that replace the 'return (val);'
with 'return;' statement, and a c_assert_if_fail that doesn't have any
return so it acts as a pass through for cases when an 'early-exit'
response isn't required (an example would be putting a constraint that
informs the user when strlcat truncates its result, as a truncation is
likely a serious error, but not fatal to the program since truncation
is defined as valid semantics for the function).
Just as 'assert' is disabled by NDEBUG, one can define a preprocessor
symbol to disable evaluation of these macros at library level, or at
source level with a granularity that depends on how many source files
one uses to implement a module. If 'range_set_node_get_start',
'range_set_node_get_end', and 'range_set_node_get_width' are all
defined in different source .c files, one can use the build system to
control which functions get compiled with or without constraint
checking (in my case, by defining C_NO_CONSTRAINTS). It's even
possible to do it at run-time if the 'report' or 'response' function
pointer check a global status value.
The result is that more of the library's assumptions can be enforced
within the framework of a single architecture with more flexibility
offered that by using 'assert' or manual defensive programming
techniques. If one wants to use this system in a design-by-contract
style, simply wire the 'response' function pointer to 'abort', which
ensures that a 'c_return_value_if_fail' will stop in its tracks. Or
one can place a breakpoint in an empty response function pointer to
stop at each constraint violation while still maintaining the
defensive style of 'c_return_value_if_fail' for production
environments.
For example, here is my version of strlcat that I use, that validates
that the source and destination strings reference memory, and warns if
the truncation occurs.
size_t c_strlcat( char* dst, const char* src, size_t dst_size )
{
size_t dst_length;
char* d = dst;
const char* s = src;
size_t n = dst_size;
size_t dlen;
c_return_value_if_fail( dst != NULL, 0 )
c_return_value_if_fail( src != NULL, 0 );
/* Find the end of dst and adjust bytes left but don't go past end.
*/
while ( *d != '\0' && n-- != 0 ) {
++d;
}
dlen = d - dst;
n = dst_size - dlen;
if ( n == 0 ) {
return dlen + strlen( s );
}
while ( *s != '\0' )
{
if ( n != 1 )
{
*d++ = *s;
--n;
}
++s;
}
*d = '\0';
/* count does not include NUL character */
dst_length = dlen + (s - src);
c_assert_if_fail( dst_length < dst_size );
return dst_length;
}
\endcode
If I get a constraint violation, I get a message like the following.
\result
Constraint violation: dst_length < dst_size, file strops.c, line 326
\end result
If one wanted to annotate these constraints, I simply add a '&&
"constraint annotation"' to the expression.
\code snippet
c_assert_if_fail( dst_length < dst_size && "buffer truncation" );
\endcode
The point is that it's possible to create an architecture that
enforces many of the module's constraints in a *consistent* manner
that is useful (since as the library writer, you're the one with the
best knowledge and the most control). Even if it doesn't satisfy all
the people, all the time, one can still write wrappers around these
functions and hard-define C_NO_CONSTRAINTS to reduce the error
checking to nothing which allows people the freedom to completely
customize their error handling behavior absent of any constraint
checking the library provides. In the ideal case, it should reduce
the support needed to help the general user-base interface with the
module.
So for your functions, I would have no problem writing them like the
following (the value of '0' in the examples could be a named constant
if more applicable).
\code snippet
/* A node in the range set. */
struct range_set_node
{
struct bt_node bt_node; /* Binary tree node. */
unsigned long int start; /* Start of region. */
unsigned long int end; /* One past end of region. */
};
/* Returns the position of the first 1-bit in NODE. */
static inline unsigned long int
range_set_node_get_start (const struct range_set_node *node)
{
c_return_value_if_fail( node != NULL, 0 );
return node->start;
}
/* Returns one past the position of the last 1-bit in NODE. */
static inline unsigned long int
range_set_node_get_end (const struct range_set_node *node)
{
c_return_value_if_fail( node != NULL, 0 );
return node->end;
}
/* Returns the number of contiguous 1-bits in NODE. */
static inline unsigned long int
range_set_node_get_width (const struct range_set_node *node)
{
c_return_value_if_fail( node != NULL, 0 );
return node->end - node->start;
}
\endcode
Even though there may be some conflict where the value '0' is a valid
semantic value, the report portion of a constraint violation is often
enough to trigger the developer to quickly fix the error and move on,
or at least recognize that something wrong may be going on and the
result may be invalid. It's more informative to the developer and the
user than just crashing the program. And if one wants blistering
speed, define C_NO_CONSTRAINTS to disable constraint checking and
throw caution to the wind. It's also better than pure defensive
programming, especially scenarios where an error return value shares
the same domain as valid return values. For example, one can return 0
as a result of a NULL pointer constraint violation detected in
strlcat, but it doesn't distinguish it from a valid value of 0 when
copying an empty string "".
It's important to recognize that these macros often can just verify a
partial view of a module's preconditions. That's why it's important
to document explicit preconditions (depending on the formal-ness of
the code) as well as any constraints one can verify in code. Even if
one cannot validate all properties of the preconditions of a module,
checking a subset of those conditions can still be very powerful.
Most of the time, I place constraint checking on all arguments when
applicable to public module functions, but not on private functions.
But, the more complicated a private function is, the more likely I
will add constraints to it (typically of the 'c_assert_if_fail'
variety).
I've been "simulated annealing" on this for quite a while, but I
recognize that there is no one best solution. And I'm sure there are
rocks that one could throw at this setup (like the lack of __func__ to
allow function names; it's still in the annealing phase). All I can
say is that from my personal experience, this scheme's value exceeds
that of 'assert' and the GLib g_return[_val]_if_fail macros. It
allows one to switch quite easily from the defensive programming style
to the contract programming style with a minimal change in its
'response' function pointer. It's as close to the best of both worlds
that I have come up with.
In Navia's case, for any pointer validation beyond semantic checking
for NULL, I would highly recommend not placing it within any library
API other than an allocator that centers on creating "heavy
pointers". If one wants to decorate pointers to dynamically allocated
memory blocks with its allocated size to track how much allocated
memory the application currently uses, or fence checking to place
magic numbers to try to detect memory corruption, determine ALIGN_MAX
to properly align and stack the decorations on the pointer and use
custom allocator routines. Or rely on a memory debugger framework
like valgrind, dmalloc, ... life's too short to reinvent this wheel.
Best regards,
John D.
[toc] | [prev] | [next] | [standalone]
| From | jacob navia <jacob@spamsink.net> |
|---|---|
| Date | 2011-09-19 22:45 +0200 |
| Message-ID | <j589ls$nv9$1@speranza.aioe.org> |
| In reply to | #10517 |
Thanks for your very informative message John Excellent. jacob
[toc] | [prev] | [next] | [standalone]
Page 2 of 15 — ← Prev page 1 [2] 3 4 … 15 Next page →
Back to top | Article view | comp.lang.c
csiph-web