Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #100623 > unrolled thread
| Started by | Veek M <vek.m1234@gmail.com> |
|---|---|
| First post | 2016-12-30 11:35 +0530 |
| Last post | 2016-12-31 07:37 +0530 |
| Articles | 20 on this page of 102 — 18 participants |
Back to article view | Back to comp.lang.c
How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Veek M <vek.m1234@gmail.com> - 2016-12-30 11:35 +0530
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Veek M <vek.m1234@gmail.com> - 2016-12-30 11:39 +0530
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Barry Schwarz <schwarzb@dqel.com> - 2016-12-29 22:24 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); raltbos@xs4all.nl (Richard Bos) - 2017-01-01 10:56 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-02 02:40 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); raltbos@xs4all.nl (Richard Bos) - 2017-01-03 21:09 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-13 16:30 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Keith Thompson <kst-u@mib.org> - 2016-12-29 23:35 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); jt@toerring.de (Jens Thoms Toerring) - 2016-12-30 09:59 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2016-12-30 10:43 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-30 12:55 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2016-12-30 13:12 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-30 14:37 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2016-12-30 16:06 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Keith Thompson <kst-u@mib.org> - 2016-12-30 08:41 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2016-12-30 17:31 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-30 19:20 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2016-12-30 19:41 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); supercat@casperkitty.com - 2016-12-30 12:46 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-31 00:31 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); supercat@casperkitty.com - 2016-12-30 11:50 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); raltbos@xs4all.nl (Richard Bos) - 2017-01-01 10:54 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-01 11:35 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-01 12:00 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-01 12:16 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-01 13:03 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-01 14:52 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-01 15:42 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-01 16:14 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-01 17:18 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Keith Thompson <kst-u@mib.org> - 2017-01-01 13:09 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-01 19:24 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); bart4858@gmail.com - 2017-01-01 11:24 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-01 20:05 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Keith Thompson <kst-u@mib.org> - 2017-01-01 13:11 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-01 22:25 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-02 02:00 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-01 13:51 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-01 21:59 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-01 14:34 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-02 02:09 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-02 05:44 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-02 15:18 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-02 15:21 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-02 17:07 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-02 09:53 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-02 23:37 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-02 15:07 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ian Collins <ian-news@hotmail.com> - 2017-01-03 12:11 +1300
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-02 15:46 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-03 00:54 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-03 00:33 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-03 11:11 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-03 11:32 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-03 14:05 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-03 14:23 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-03 16:04 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-03 16:09 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-03 17:23 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); supercat@casperkitty.com - 2017-01-03 09:00 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-03 20:33 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); luser droog <luser.droog@gmail.com> - 2017-01-03 11:40 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); supercat@casperkitty.com - 2017-01-03 12:23 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); luser droog <luser.droog@gmail.com> - 2017-01-03 12:39 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); supercat@casperkitty.com - 2017-01-03 13:51 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-15 22:58 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); supercat@casperkitty.com - 2017-01-16 10:24 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-31 08:36 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Tim Rentsch <txr@alumni.caltech.edu> - 2017-01-14 00:53 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ian Collins <ian-news@hotmail.com> - 2017-01-03 13:13 +1300
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Keith Thompson <kst-u@mib.org> - 2017-01-02 15:51 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-03 00:51 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); jt@toerring.de (Jens Thoms Toerring) - 2017-01-02 23:32 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-02 23:46 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-03 01:00 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-03 00:42 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ian Collins <ian-news@hotmail.com> - 2017-01-03 21:47 +1300
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-03 01:31 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-03 10:34 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-03 11:19 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-03 16:19 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Thompson <dave.thompson2@verizon.net> - 2017-01-18 07:51 -0500
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Gareth Owen <gwowen@gmail.com> - 2017-01-18 21:30 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Richard Heathfield <rjh@cpax.org.uk> - 2017-01-18 21:45 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); raltbos@xs4all.nl (Richard Bos) - 2017-01-18 21:55 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Gareth Owen <gwowen@gmail.com> - 2017-01-19 22:25 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-02 00:08 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-02 02:05 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Malcolm McLean <malcolm.mclean5@btinternet.com> - 2017-01-01 09:45 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-01 19:20 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); supercat@casperkitty.com - 2017-01-01 15:26 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2017-01-01 23:48 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-02 00:25 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2017-01-01 16:44 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Philip Lantz <prl@canterey.us> - 2017-01-01 23:54 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Keith Thompson <kst-u@mib.org> - 2017-01-01 13:25 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-01 22:36 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); supercat@casperkitty.com - 2017-01-01 15:38 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); BartC <bc@freeuk.com> - 2016-12-30 13:42 +0000
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); David Brown <david.brown@hesbynett.no> - 2016-12-30 15:07 +0100
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); supercat@casperkitty.com - 2016-12-30 10:21 -0800
Re: How is he doing: int a[2] = { 1, 2 }; printf("%d\n", 2[a]); Veek M <vek.m1234@gmail.com> - 2016-12-31 07:37 +0530
Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6 Next page →
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-02 02:09 +0100 |
| Message-ID | <o4c95s$gg$1@dont-email.me> |
| In reply to | #100826 |
On 01/01/17 23:34, Malcolm McLean wrote:
> On Sunday, January 1, 2017 at 9:59:47 PM UTC, Bart wrote:
>> On 01/01/2017 21:51, Malcolm McLean wrote:
>>> On Sunday, January 1, 2017 at 8:05:07 PM UTC, Ben Bacarisse wrote:
>>>> bart4858@gmail.com writes:
>>>>
>>>>> I don't think people use _Bool enough to know the rules
>>>>> precisely.
>>>>
>>>> It's a good idea to learn the rules even if you only use _Bool once or
>>>> twice but that is, I think, an unfashionable approach to programming.
>>>>
>>> The problem is there is far too much of this garbage in programming.
>>>
>>> A type which holds a flag that is set or unset, but with some sort of
>>> difficulty or complexity about it which means you really need to
>>> dig out the manual. Just use an int and set it to 1 or 0, the fancy
>>> types give no additional functionality, just complications.
>>
>>
>> Exactly. I've never bothered much with bool [implementing it elsewhere]
>> for these reasons.
>>
>> To do it properly, you'd have to implement half of Ada.
>>
> The other thing is that boolean parameters are a bad idea. Let's
> say we're created an "imagebutton" and maintainer sees this code
>
> reset_but = imagebutton("reset_but.gif", 32, 32, do_reset, true);
>
> nothing odd there. 32 and 32 are probably with width and height
> in pixels, do_reset will be a function pointer Except what exactly
> is the boolean parameter?
>
> if we pass
>
> reset_but = imagebutton("reset_but.gif", 32, 32, do_reset, ALLOW_TRANSPARENT);
>
> it's obvious. The button is a gif, and it has transparency associated
> with it.
>
> So it makes a lot more sense to make the parameter an enumerated type
> or an integer, even if in fact it is logically bi-valued.
>
Exactly the same argument applies to the int parameters. You need to
know which int refers to the width, and which refers to the height -
just as you need to know what the boolean parameters refer to. You
solve the "problem" in the same way - use clear parameter names your
headers with the function declaration, and document your functions
appropriately.
In C, using a named enumerated type does not help much since there is no
checking on the type. It helps in C++, which has checking.
(The best solution, for both C and C++, would be to introduce named
parameters to the language. But even in C++, suggestions for named
parameter schemes have not made it into the language.)
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2017-01-02 05:44 -0800 |
| Message-ID | <8a116d18-8ccd-4801-af92-2db08744a34c@googlegroups.com> |
| In reply to | #100845 |
On Monday, January 2, 2017 at 1:09:48 AM UTC, David Brown wrote:
> On 01/01/17 23:34, Malcolm McLean wrote:
> > On Sunday, January 1, 2017 at 9:59:47 PM UTC, Bart wrote:
> >> On 01/01/2017 21:51, Malcolm McLean wrote:
> >>> On Sunday, January 1, 2017 at 8:05:07 PM UTC, Ben Bacarisse wrote:
> >>>> bart4858@gmail.com writes:
> >>>>
> >>>>> I don't think people use _Bool enough to know the rules
> >>>>> precisely.
> >>>>
> >>>> It's a good idea to learn the rules even if you only use _Bool once or
> >>>> twice but that is, I think, an unfashionable approach to programming.
> >>>>
> >>> The problem is there is far too much of this garbage in programming.
> >>>
> >>> A type which holds a flag that is set or unset, but with some sort of
> >>> difficulty or complexity about it which means you really need to
> >>> dig out the manual. Just use an int and set it to 1 or 0, the fancy
> >>> types give no additional functionality, just complications.
> >>
> >>
> >> Exactly. I've never bothered much with bool [implementing it elsewhere]
> >> for these reasons.
> >>
> >> To do it properly, you'd have to implement half of Ada.
> >>
> > The other thing is that boolean parameters are a bad idea. Let's
> > say we're created an "imagebutton" and maintainer sees this code
> >
> > reset_but = imagebutton("reset_but.gif", 32, 32, do_reset, true);
> >
> > nothing odd there. 32 and 32 are probably with width and height
> > in pixels, do_reset will be a function pointer Except what exactly
> > is the boolean parameter?
> >
> > if we pass
> >
> > reset_but = imagebutton("reset_but.gif", 32, 32, do_reset, ALLOW_TRANSPARENT);
> >
> > it's obvious. The button is a gif, and it has transparency associated
> > with it.
> >
> > So it makes a lot more sense to make the parameter an enumerated type
> > or an integer, even if in fact it is logically bi-valued.
> >
>
> Exactly the same argument applies to the int parameters. You need to
> know which int refers to the width, and which refers to the height -
> just as you need to know what the boolean parameters refer to. You
> solve the "problem" in the same way - use clear parameter names your
> headers with the function declaration, and document your functions
> appropriately.
>
Not really, because either the int is a named variable (icon_width or#something, in which case it is obvious) or it is a literal, and
two values of 32 pretty much have to be width / height. Occasionally
yes you'll guess wrong, maybe they are x, y, but the code is largely
meaningful. A value of true or false could mean almost anything,
even a function like enable_button(true). Is there a matching
disable_button() or do we pass enable_button(false)?
>
> In C, using a named enumerated type does not help much since there is no
> checking on the type. It helps in C++, which has checking.
>
Type checking is something which the compiler can do easily. It's
just a minor help to the programmer, as passing the wrong type isn't
a bug that is likely to endure.
>
> (The best solution, for both C and C++, would be to introduce named
> parameters to the language. But even in C++, suggestions for named
> parameter schemes have not made it into the language.)
>
You can do it in C
int namedparam(const char *name1, ...)
{
va_list va;
va_start(va, name1);
const char *currentname = name1;
double x, y, z; // parameters
while(currentname)
{
if(!strcmp(currentname, "x"))
x = va_arg(va, double);
etc
currentname = va_arg(va, const char *)
}
va_end(va):
}
But it's something I've seen very rarely.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-02 15:18 +0100 |
| Message-ID | <o4dnc3$qaq$1@dont-email.me> |
| In reply to | #100871 |
On 02/01/17 14:44, Malcolm McLean wrote:
> On Monday, January 2, 2017 at 1:09:48 AM UTC, David Brown wrote:
>> On 01/01/17 23:34, Malcolm McLean wrote:
>>> On Sunday, January 1, 2017 at 9:59:47 PM UTC, Bart wrote:
>>>> On 01/01/2017 21:51, Malcolm McLean wrote:
>>>>> On Sunday, January 1, 2017 at 8:05:07 PM UTC, Ben Bacarisse wrote:
>>>>>> bart4858@gmail.com writes:
>>>>>>
>>>>>>> I don't think people use _Bool enough to know the rules
>>>>>>> precisely.
>>>>>>
>>>>>> It's a good idea to learn the rules even if you only use _Bool once or
>>>>>> twice but that is, I think, an unfashionable approach to programming.
>>>>>>
>>>>> The problem is there is far too much of this garbage in programming.
>>>>>
>>>>> A type which holds a flag that is set or unset, but with some sort of
>>>>> difficulty or complexity about it which means you really need to
>>>>> dig out the manual. Just use an int and set it to 1 or 0, the fancy
>>>>> types give no additional functionality, just complications.
>>>>
>>>>
>>>> Exactly. I've never bothered much with bool [implementing it elsewhere]
>>>> for these reasons.
>>>>
>>>> To do it properly, you'd have to implement half of Ada.
>>>>
>>> The other thing is that boolean parameters are a bad idea. Let's
>>> say we're created an "imagebutton" and maintainer sees this code
>>>
>>> reset_but = imagebutton("reset_but.gif", 32, 32, do_reset, true);
>>>
>>> nothing odd there. 32 and 32 are probably with width and height
>>> in pixels, do_reset will be a function pointer Except what exactly
>>> is the boolean parameter?
>>>
>>> if we pass
>>>
>>> reset_but = imagebutton("reset_but.gif", 32, 32, do_reset, ALLOW_TRANSPARENT);
>>>
>>> it's obvious. The button is a gif, and it has transparency associated
>>> with it.
>>>
>>> So it makes a lot more sense to make the parameter an enumerated type
>>> or an integer, even if in fact it is logically bi-valued.
>>>
>>
>> Exactly the same argument applies to the int parameters. You need to
>> know which int refers to the width, and which refers to the height -
>> just as you need to know what the boolean parameters refer to. You
>> solve the "problem" in the same way - use clear parameter names your
>> headers with the function declaration, and document your functions
>> appropriately.
>>
> Not really, because either the int is a named variable (icon_width
> or something, in which case it is obvious) or it is a literal, and
> two values of 32 pretty much have to be width / height.
Yes, really, because /exactly the same thing applies to bools/.
handle imagebutton(const char* name, int width, int height, action_t
action, bool allow_transparent);
Why do you think it is somehow "clearer" what the two int parameters do,
than what the bool parameter does? And how could it possibly be
"better" by making the bool parameter an "int"? Just pick a decent name
for the parameter, and stop inventing problems.
And if you still feel this is too difficult to follow, you can also do:
static const bool ALLOW_TRANSPARENT = true;
static const bool NO_ALLOW_TRANSPARENT = false;
and then you can pass ALLOW_TRANSPARENT as the argument.
> Occasionally
> yes you'll guess wrong, maybe they are x, y, but the code is largely
> meaningful. A value of true or false could mean almost anything,
An int can mean almost anything - unless you give it a sensible name.
> even a function like enable_button(true). Is there a matching
> disable_button() or do we pass enable_button(false)?
Baring documentation to the contrary, if "enable_button" takes a bool
parameter, then "true" would enable the button and "false" disable it.
It would be weird to have a "disable_button" function with no parameters
when there is an "enable_button" with a bool, at least in the context of
C. In C++, you might have "enable_button" with a bool that defaults to
true, and also a "disable_button" with no parameters.
This is all pretty obvious. On the other hand, if you have
"enable_button(int)", you have no idea what it does without looking up
the details such as the parameter name.
>>
>> In C, using a named enumerated type does not help much since there is no
>> checking on the type. It helps in C++, which has checking.
>>
> Type checking is something which the compiler can do easily. It's
> just a minor help to the programmer, as passing the wrong type isn't
> a bug that is likely to endure.
No, it is not something the compiler can do easily - you mostly have to
wrap your real data inside a struct to be sure that you will get a
compiler error on the wrong type. For C++, you do this naturally with
your own classes, and things like enum classes, constructors, conversion
operators, user-defined literals, etc., make it easy to use multiple
types. For C, you need to work with the structs manually or with
functions/macros, so it is usually only done when it is really important.
And type checking is more than a minor help - precisely because passing
the wrong type can be a bug that long goes unnoticed.
>>
>> (The best solution, for both C and C++, would be to introduce named
>> parameters to the language. But even in C++, suggestions for named
>> parameter schemes have not made it into the language.)
>>
> You can do it in C
>
> int namedparam(const char *name1, ...)
> {
> va_list va;
> va_start(va, name1);
> const char *currentname = name1;
>
> double x, y, z; // parameters
>
> while(currentname)
> {
> if(!strcmp(currentname, "x"))
> x = va_arg(va, double);
>
> etc
>
> currentname = va_arg(va, const char *)
> }
> va_end(va):
> }
>
> But it's something I've seen very rarely.
>
That is not "named parameters". It is just an unsafe, unchecked,
illegible, unscalable, inefficient mess.
Named parameters would be something like:
void draw_rect(int left, int top, int width, int height,
bool fill_rect = false);
int main() {
// Both of the function calls below pass the same set of
// arguments to draw_rect.
draw_rect(top: 10, left: 100, width: 640, height: 480);
draw_rect(100, 10, height: 480, fill_rect: false, width: 640);
}
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-01-02 15:21 +0000 |
| Message-ID | <o4dr32$7s5$1@dont-email.me> |
| In reply to | #100875 |
On 02/01/2017 14:18, David Brown wrote:
> On 02/01/17 14:44, Malcolm McLean wrote:
> And type checking is more than a minor help - precisely because passing
> the wrong type can be a bug that long goes unnoticed.
Unless you've passed the wrong category of pointer, then the programmer
will always know immediately without being told!
void fn(int* A){printf("%d\n",A[123]);}
...
int A=0;
fn(&A);
>> int namedparam(const char *name1, ...)
>> {
>> va_list va;
>> va_start(va, name1);
>> const char *currentname = name1;
>>
>> double x, y, z; // parameters
>>
>> while(currentname)
>> {
>> if(!strcmp(currentname, "x"))
>> x = va_arg(va, double);
>>
>> etc
>>
>> currentname = va_arg(va, const char *)
>> }
>> va_end(va):
>> }
> That is not "named parameters". It is just an unsafe, unchecked,
> illegible, unscalable, inefficient mess.
Agreed...
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-02 17:07 +0100 |
| Message-ID | <o4dtor$hdj$1@dont-email.me> |
| In reply to | #100876 |
On 02/01/17 16:21, BartC wrote:
> On 02/01/2017 14:18, David Brown wrote:
>> On 02/01/17 14:44, Malcolm McLean wrote:
>
>> And type checking is more than a minor help - precisely because passing
>> the wrong type can be a bug that long goes unnoticed.
>
> Unless you've passed the wrong category of pointer, then the programmer
> will always know immediately without being told!
>
> void fn(int* A){printf("%d\n",A[123]);}
> ...
> int A=0;
> fn(&A);
>
That is true for pointer types, but not for scaler types - integer types
of different sizes, bools, floats, enums. These are generally silently
converted from one type to another when you supply one type as a
function argument and the function was declared with a parameter of a
different type. Mostly, that is convenient. But if you want to use
type checking to help for argument passing, you have to go a bit out of
your way.
For example, if you have a function "makeIcon" that takes two int
parameters, one for height and one for width, you can wrap these in
structs to make sure that you call them in the correct order:
typedef struct width_t { int w; } width_t;
#define width(w) ((width_t) {w})
typedef struct height_t { int h; } height_t;
#define height(h) ((height_t) {h})
void makeIcon(width_t w, height_t h);
Then this works:
void test(int w, int h) {
makeIcon(width(w), height(h));
}
But this gives a compiler error:
void test(int w, int h) {
makeIcon(height(h), width(w));
}
Thus you have used type checking to make sure that you have the
parameter order correct - it is a sort-of named parameter solution. But
it is ugly, verbose, and fills the global namespace with extra identifiers.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2017-01-02 09:53 -0800 |
| Message-ID | <b7c31c9b-d7f0-4042-852d-64a0e86af2cc@googlegroups.com> |
| In reply to | #100879 |
On Monday, January 2, 2017 at 4:07:25 PM UTC, David Brown wrote:
> On 02/01/17 16:21, BartC wrote:
> > On 02/01/2017 14:18, David Brown wrote:
> >> On 02/01/17 14:44, Malcolm McLean wrote:
> >
> >> And type checking is more than a minor help - precisely because passing
> >> the wrong type can be a bug that long goes unnoticed.
> >
> > Unless you've passed the wrong category of pointer, then the programmer
> > will always know immediately without being told!
> >
> > void fn(int* A){printf("%d\n",A[123]);}
> > ...
> > int A=0;
> > fn(&A);
> >
>
> That is true for pointer types, but not for scaler types - integer types
> of different sizes, bools, floats, enums. These are generally silently
> converted from one type to another when you supply one type as a
> function argument and the function was declared with a parameter of a
> different type. Mostly, that is convenient. But if you want to use
> type checking to help for argument passing, you have to go a bit out of
> your way.
>
> For example, if you have a function "makeIcon" that takes two int
> parameters, one for height and one for width, you can wrap these in
> structs to make sure that you call them in the correct order:
>
> typedef struct width_t { int w; } width_t;
> #define width(w) ((width_t) {w})
>
> typedef struct height_t { int h; } height_t;
> #define height(h) ((height_t) {h})
>
> void makeIcon(width_t w, height_t h);
>
> Then this works:
>
> void test(int w, int h) {
> makeIcon(width(w), height(h));
> }
>
> But this gives a compiler error:
>
> void test(int w, int h) {
> makeIcon(height(h), width(w));
> }
>
>
> Thus you have used type checking to make sure that you have the
> parameter order correct - it is a sort-of named parameter solution.
> But it is ugly, verbose, and fills the global namespace with extra
> identifiers.
>
Yes, it's no answer.
But if we do this
void makeIcon(int height, int width);
Eiffel_tower = makeIcon(16, 64);
We've reversed the convention, because height precedes width.
Bu thre bug won't persist. The informal tester will take one look
at that icon and say "width and height have been flipped".
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-02 23:37 +0100 |
| Message-ID | <o4ekko$5ts$1@dont-email.me> |
| In reply to | #100884 |
On 02/01/17 18:53, Malcolm McLean wrote: > > But if we do this > > void makeIcon(int height, int width); > > > Eiffel_tower = makeIcon(16, 64); > > We've reversed the convention, because height precedes width. > Bu thre bug won't persist. The informal tester will take one look > at that icon and say "width and height have been flipped". > > This is back to relying on parameter names again - nothing more. And to go back full circle to your complaint about bools, this is exactly the same as you can do with bool arguments. If it is good enough for int arguments, it is good enough for bools.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2017-01-02 15:07 -0800 |
| Message-ID | <8354468b-4d6e-4f7e-b6fa-e02f8e89c7a4@googlegroups.com> |
| In reply to | #100917 |
On Monday, January 2, 2017 at 10:37:45 PM UTC, David Brown wrote: > On 02/01/17 18:53, Malcolm McLean wrote: > > > > > But if we do this > > > > void makeIcon(int height, int width); > > > > > > Eiffel_tower = makeIcon(16, 64); > > > > We've reversed the convention, because height precedes width. > > Bu thre bug won't persist. The informal tester will take one look > > at that icon and say "width and height have been flipped". > > > > > > This is back to relying on parameter names again - nothing more. And to > go back full circle to your complaint about bools, this is exactly the > same as you can do with bool arguments. If it is good enough for int > arguments, it is good enough for bools. > Firstly, a bool literal is abstracted as "true" or "false", seldom as "SET_TRANSPARENT_MODE". An int literal is likely to be #defined EIFFEL_TOWER_HEIGHT, or assigned to a variable (int height = 64;). Secondly, even if you do see an int literal in the code, typically the number is a bit meaningful. You know the icons are going to be small images, so values, like 32, 64 are probably dimensions, values like 24, 193 more likely to be x, y co-ordinates. Again, you're quite likely to see something like winheight - 27 in real code, so you know that the parameter is the y coordinate of the image, and is 27 pixels above the bottom of the window. Arguments of "true" and "false" are just meaningless, however. Only by actually looking up the cal can you tell what they mean. Ad often calls have many parameters, and there's logic in the call expression. So you have to count the arguments to work out what the booleans values represent. It's not an insurmountable problem, but it makes programs harder to read than they would otherwise be.
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2017-01-03 12:11 +1300 |
| Message-ID | <ed051qFlsf9U5@mid.individual.net> |
| In reply to | #100922 |
On 01/ 3/17 12:07 PM, Malcolm McLean wrote: > On Monday, January 2, 2017 at 10:37:45 PM UTC, David Brown wrote: >> On 02/01/17 18:53, Malcolm McLean wrote: >> >>> >>> But if we do this >>> >>> void makeIcon(int height, int width); >>> >>> >>> Eiffel_tower = makeIcon(16, 64); >>> >>> We've reversed the convention, because height precedes width. >>> Bu thre bug won't persist. The informal tester will take one look >>> at that icon and say "width and height have been flipped". >>> >>> >> >> This is back to relying on parameter names again - nothing more. And to >> go back full circle to your complaint about bools, this is exactly the >> same as you can do with bool arguments. If it is good enough for int >> arguments, it is good enough for bools. >> > Firstly, a bool literal is abstracted as "true" or "false", seldom as > "SET_TRANSPARENT_MODE". An int literal is likely to be #defined > EIFFEL_TOWER_HEIGHT, or assigned to a variable (int height = 64;). Says who? Why wouldn't bool constants be named any differently from integer ones? -- Ian
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2017-01-02 15:46 -0800 |
| Message-ID | <83a7f23a-e96a-4282-b003-1814998edbad@googlegroups.com> |
| In reply to | #100923 |
On Monday, January 2, 2017 at 11:12:03 PM UTC, Ian Collins wrote: > On 01/ 3/17 12:07 PM, Malcolm McLean wrote: > > On Monday, January 2, 2017 at 10:37:45 PM UTC, David Brown wrote: > >> On 02/01/17 18:53, Malcolm McLean wrote: > >> > >>> > >>> But if we do this > >>> > >>> void makeIcon(int height, int width); > >>> > >>> > >>> Eiffel_tower = makeIcon(16, 64); > >>> > >>> We've reversed the convention, because height precedes width. > >>> Bu thre bug won't persist. The informal tester will take one look > >>> at that icon and say "width and height have been flipped". > >>> > >>> > >> > >> This is back to relying on parameter names again - nothing more. And to > >> go back full circle to your complaint about bools, this is exactly the > >> same as you can do with bool arguments. If it is good enough for int > >> arguments, it is good enough for bools. > >> > > Firstly, a bool literal is abstracted as "true" or "false", seldom as > > "SET_TRANSPARENT_MODE". An int literal is likely to be #defined > > EIFFEL_TOWER_HEIGHT, or assigned to a variable (int height = 64;). > > Says who? > > Why wouldn't bool constants be named any differently from integer ones? > Because "true" and "false" are considered sufficiently abstract. Many people however don't like to see the literal 42 in code. They have coding standards that suggest it be #defined or turned into a named const int. I have seen a few coding standards that discourage boolean parameters (it's not something I originated myself) but not many. It's something that needs to be spread through the community.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-03 00:54 +0100 |
| Message-ID | <o4ep4s$n7g$1@dont-email.me> |
| In reply to | #100928 |
On 03/01/17 00:46, Malcolm McLean wrote: > On Monday, January 2, 2017 at 11:12:03 PM UTC, Ian Collins wrote: >> On 01/ 3/17 12:07 PM, Malcolm McLean wrote: >>> On Monday, January 2, 2017 at 10:37:45 PM UTC, David Brown wrote: >>>> On 02/01/17 18:53, Malcolm McLean wrote: >>>> >>>>> >>>>> But if we do this >>>>> >>>>> void makeIcon(int height, int width); >>>>> >>>>> >>>>> Eiffel_tower = makeIcon(16, 64); >>>>> >>>>> We've reversed the convention, because height precedes width. >>>>> Bu thre bug won't persist. The informal tester will take one look >>>>> at that icon and say "width and height have been flipped". >>>>> >>>>> >>>> >>>> This is back to relying on parameter names again - nothing more. And to >>>> go back full circle to your complaint about bools, this is exactly the >>>> same as you can do with bool arguments. If it is good enough for int >>>> arguments, it is good enough for bools. >>>> >>> Firstly, a bool literal is abstracted as "true" or "false", seldom as >>> "SET_TRANSPARENT_MODE". An int literal is likely to be #defined >>> EIFFEL_TOWER_HEIGHT, or assigned to a variable (int height = 64;). >> >> Says who? >> >> Why wouldn't bool constants be named any differently from integer ones? >> > Because "true" and "false" are considered sufficiently abstract. > > Many people however don't like to see the literal 42 in code. > They have coding standards that suggest it be #defined or turned into > a named const int. > > I have seen a few coding standards that discourage boolean parameters > (it's not something I originated myself) but not many. It's something > that needs to be spread through the community. > > No, it is /not/ something that "needs to be spread through the community". It is /your/ personal opinion. If /you/ don't want to use bools as function parameters, that's fine - but it is /your/ idea. Don't pretend that you have had some sort of revelation and you need to convert the rest of the C programming world to the one true parameter type.
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2017-01-03 00:33 -0800 |
| Message-ID | <00cef666-7f2b-4d94-9967-a0bbbb5b68ac@googlegroups.com> |
| In reply to | #100932 |
On Monday, January 2, 2017 at 11:54:37 PM UTC, David Brown wrote: > > No, it is /not/ something that "needs to be spread through the > community". It is /your/ personal opinion. If /you/ don't want to use > bools as function parameters, that's fine - but it is /your/ idea. > Don't pretend that you have had some sort of revelation and you need to > convert the rest of the C programming world to the one true parameter type. > It's not my idea, and whilst it is stylistic issue, it's not "true for me not not necessarily true for anyone else". The decision is taken by whoever defines the API, who isn't usually the same person who writes the client code.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-03 11:11 +0000 |
| Message-ID | <8737h0jt4j.fsf@bsb.me.uk> |
| In reply to | #100952 |
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
> On Monday, January 2, 2017 at 11:54:37 PM UTC, David Brown wrote:
>>
>> No, it is /not/ something that "needs to be spread through the
>> community". It is /your/ personal opinion. If /you/ don't want to use
>> bools as function parameters, that's fine - but it is /your/ idea.
>> Don't pretend that you have had some sort of revelation and you need to
>> convert the rest of the C programming world to the one true parameter type.
>>
> It's not my idea,
Yes, it's a very old one. What's new is the confusion you've introduced
around a simple idea by suggesting that there is something odd about
naming values of some types. It has nothing to do with bool parameters
and everything to do with mysterious constants being used as arguments.
That problem has been know since the dawn of programming.
This:
reset = imagebutton("reset_but.gif", 32, 32, do_reset, true);
is just as mysterious as this:
reset = imagebutton("reset_but.gif", 32, 32, do_reset, 1);
and it makes little difference if the API is
button_t imagebutton(const char *img, int wd, int ht,
callback_t action, bool permit_transparency);
or
button_t imagebutton(const char *img, int wd, int ht,
callback_t action, int permit_transparency);
(both calls are perfectly valid for both function declarations).
Naming the magic value helps just as much in both cases:
#define ALLOW_TRANSPARENT true
...
reset = imagebutton("reset_but.gif", 32, 32, do_reset, ALLOW_TRANSPARENT);
is as reasonable
#define ALLOW_TRANSPARENT 1
...
reset = imagebutton("reset_but.gif", 32, 32, do_reset, ALLOW_TRANSPARENT);
Ironically, the bool version of the API is, in fact, slightly more
helpful because it shows that only two values are possible for that
final parameter.
You can get an even more informative call by writing
#define ALLOW_TRANSPARENCY(b) (b)
so that you write ALLOW_TRANSPARENCY(true) or ALLOW_TRANSPARENCY(false)
in the final position, but C lacks a simple way to define a unique type
with a finite number of named values[1]. In languages that permit it,
one would probably do that in this case.
> and whilst it is stylistic issue,
The int (or unsigned int) version is often preferred for engineering
reasons as it allows for further flags to be passed by interpreting the
value as a set of bits, but that's another concern altogether.
<snip>
[1] A digression... It's possible to define a type for this by using
structs and compound literals:
typedef struct { _Bool value; } transparency_t;
#define ALLOW_TRANSPARENCY(b) ((transparency_t){b})
Now, passing a value of the wrong type will be picked up at compile
time. I've not seen this done (so there may be serious pitfalls) but I
suspect that's just down to the fact the few people want to tie an API
to C99. I've used _Bool there to avoid forcing the use of stdbool.h.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-01-03 11:32 +0000 |
| Message-ID | <o4g20r$s9q$1@dont-email.me> |
| In reply to | #100962 |
On 03/01/2017 11:11, Ben Bacarisse wrote:
> Malcolm McLean <malcolm.mclean5@btinternet.com> writes:
>
>> On Monday, January 2, 2017 at 11:54:37 PM UTC, David Brown wrote:
>>>
>>> No, it is /not/ something that "needs to be spread through the
>>> community". It is /your/ personal opinion. If /you/ don't want to use
>>> bools as function parameters, that's fine - but it is /your/ idea.
>>> Don't pretend that you have had some sort of revelation and you need to
>>> convert the rest of the C programming world to the one true parameter type.
>>>
>> It's not my idea,
>
> Yes, it's a very old one. What's new is the confusion you've introduced
> around a simple idea by suggesting that there is something odd about
> naming values of some types. It has nothing to do with bool parameters
> and everything to do with mysterious constants being used as arguments.
> That problem has been know since the dawn of programming.
>
> This:
>
> reset = imagebutton("reset_but.gif", 32, 32, do_reset, true);
>
> is just as mysterious as this:
>
> reset = imagebutton("reset_but.gif", 32, 32, do_reset, 1);
>
> and it makes little difference if the API is
>
> button_t imagebutton(const char *img, int wd, int ht,
> callback_t action, bool permit_transparency);
>
> or
>
> button_t imagebutton(const char *img, int wd, int ht,
> callback_t action, int permit_transparency);
>
> (both calls are perfectly valid for both function declarations).
>
> Naming the magic value helps just as much in both cases:
>
> #define ALLOW_TRANSPARENT true
> ...
> reset = imagebutton("reset_but.gif", 32, 32, do_reset, ALLOW_TRANSPARENT);
This is effectively just assuming keyword parameters exist:
reset = imagebutton("reset_but.gif", 32, 32, do_reset,
permit_transparency:true);
but changing the ":" to "_":
#define permit_transparency_true 1
then writing:
reset = imagebutton("reset_but.gif", 32, 32, do_reset,
permit_transparency_true);
But that doesn't help with the 32s. (Nor does it allow arguments to be
omitted if they have defaults, or their order to be changed.)
(And the method becomes unwieldy when you have hundreds of functions and
possibly thousands of parameters.)
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-03 14:05 +0000 |
| Message-ID | <87r34ki6hu.fsf@bsb.me.uk> |
| In reply to | #100964 |
BartC <bc@freeuk.com> writes:
> On 03/01/2017 11:11, Ben Bacarisse wrote:
<snip>
>> Naming the magic value helps just as much in both cases:
>>
>> #define ALLOW_TRANSPARENT true
>> ...
>> reset = imagebutton("reset_but.gif", 32, 32, do_reset, ALLOW_TRANSPARENT);
>
> This is effectively just assuming keyword parameters exist:
>
> reset = imagebutton("reset_but.gif", 32, 32, do_reset,
> permit_transparency:true);
I suppose. Except for all the ways it which it's different.
> but changing the ":" to "_":
>
> #define permit_transparency_true 1
>
> then writing:
>
> reset = imagebutton("reset_but.gif", 32, 32, do_reset,
> permit_transparency_true);
I see no gain from the _true and I would want the macro to be in ALL
CAPS, but each to their own. I prefer the macro you didn't comment on
#define ALLOW_TRASPARENCY(b) (b)
> But that doesn't help with the 32s.
No, it was not meant to. None of this really provides anything like
keyword arguments.
<snip>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | BartC <bc@freeuk.com> |
|---|---|
| Date | 2017-01-03 14:23 +0000 |
| Message-ID | <o4gc1n$ht$1@dont-email.me> |
| In reply to | #100977 |
On 03/01/2017 14:05, Ben Bacarisse wrote:
> BartC <bc@freeuk.com> writes:
>> then writing:
>>
>> reset = imagebutton("reset_but.gif", 32, 32, do_reset,
>> permit_transparency_true);
>
> I see no gain from the _true
There might be a corresponding permit_transparency_false.
and I would want the macro to be in ALL
> CAPS, but each to their own. I prefer the macro you didn't comment on
>
> #define ALLOW_TRANSPARENCY(b) (b)
That's another way doing the same thing (although I made mine match the
name in the prototype).
Both have the problem in that, if you have a bunch of functions and
loads of such parameters, you now need a collection of corresponding
macros to go with them. (And OK, my way might need twice the number!)
In which case it might be better to go low tech:
reset = imagebutton("reset_but.gif", 32, 32, do_reset,
/*permit_transparency:*/ true);
(Although this doesn't give the error-checking and other benefits of
keyword params.)
--
Bartc
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-03 16:04 +0100 |
| Message-ID | <o4geeb$9cj$1@dont-email.me> |
| In reply to | #100962 |
On 03/01/17 12:11, Ben Bacarisse wrote:
>
> [1] A digression... It's possible to define a type for this by using
> structs and compound literals:
>
> typedef struct { _Bool value; } transparency_t;
> #define ALLOW_TRANSPARENCY(b) ((transparency_t){b})
>
> Now, passing a value of the wrong type will be picked up at compile
> time. I've not seen this done (so there may be serious pitfalls) but I
> suspect that's just down to the fact the few people want to tie an API
> to C99. I've used _Bool there to avoid forcing the use of stdbool.h.
>
I mentioned this method in one of my posts. The main problem, I think,
is scalability. It is not a bad method if you have lots of API calls
that share only a few of these new types - such as if lots of the
functions need a "transparency" parameter. But it quickly becomes
messy, and floods the global namespace, when you have lots of parameters
to wrap in this way. And if you don't have lots of parameters, then
there is less benefit in having such type safety!
I have seen this kind of wrapping done for a few "critical" types -
things like resource handles for an OS, where it can help avoid accidents.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-03 16:09 +0000 |
| Message-ID | <871swki0q3.fsf@bsb.me.uk> |
| In reply to | #100990 |
David Brown <david.brown@hesbynett.no> writes:
> On 03/01/17 12:11, Ben Bacarisse wrote:
>>
>> [1] A digression... It's possible to define a type for this by using
>> structs and compound literals:
>>
>> typedef struct { _Bool value; } transparency_t;
>> #define ALLOW_TRANSPARENCY(b) ((transparency_t){b})
>>
>> Now, passing a value of the wrong type will be picked up at compile
>> time. I've not seen this done (so there may be serious pitfalls) but I
>> suspect that's just down to the fact the few people want to tie an API
>> to C99. I've used _Bool there to avoid forcing the use of stdbool.h.
>>
>
> I mentioned this method in one of my posts.
Ah, sorry. I'm not always paying full attention.
<snip>
> I have seen this kind of wrapping done for a few "critical" types -
> things like resource handles for an OS, where it can help avoid
> accidents.
I my experience opaque types are more common (and indeed useful) for
that with sometimes a few named external objects, but I don't think I've
seen compound literal used to construct values are run-time.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-03 17:23 +0100 |
| Message-ID | <o4gj3b$pkn$1@dont-email.me> |
| In reply to | #101005 |
On 03/01/17 17:09, Ben Bacarisse wrote:
> David Brown <david.brown@hesbynett.no> writes:
>
>> On 03/01/17 12:11, Ben Bacarisse wrote:
>>>
>>> [1] A digression... It's possible to define a type for this by using
>>> structs and compound literals:
>>>
>>> typedef struct { _Bool value; } transparency_t;
>>> #define ALLOW_TRANSPARENCY(b) ((transparency_t){b})
>>>
>>> Now, passing a value of the wrong type will be picked up at compile
>>> time. I've not seen this done (so there may be serious pitfalls) but I
>>> suspect that's just down to the fact the few people want to tie an API
>>> to C99. I've used _Bool there to avoid forcing the use of stdbool.h.
>>>
>>
>> I mentioned this method in one of my posts.
>
> Ah, sorry. I'm not always paying full attention.
>
> <snip>
>> I have seen this kind of wrapping done for a few "critical" types -
>> things like resource handles for an OS, where it can help avoid
>> accidents.
>
> I my experience opaque types are more common (and indeed useful) for
> that with sometimes a few named external objects, but I don't think I've
> seen compound literal used to construct values are run-time.
>
The construction and access to that kind of type is usually hidden
within macros. I don't know if compound literals are used to implement
such macros, but it is certainly a possibility.
[toc] | [prev] | [next] | [standalone]
| From | supercat@casperkitty.com |
|---|---|
| Date | 2017-01-03 09:00 -0800 |
| Message-ID | <3a78c045-a55e-4f54-b525-76acd6c7af52@googlegroups.com> |
| In reply to | #101007 |
On Tuesday, January 3, 2017 at 10:23:42 AM UTC-6, David Brown wrote:
> On 03/01/17 17:09, Ben Bacarisse wrote:
> > I my experience opaque types are more common (and indeed useful) for
> > that with sometimes a few named external objects, but I don't think I've
> > seen compound literal used to construct values are run-time.
> >
>
> The construction and access to that kind of type is usually hidden
> within macros. I don't know if compound literals are used to implement
> such macros, but it is certainly a possibility.
Compound literals are often only useful with types that are passed by value.
Given an external function definition like
void useThingie(struct foo const *restrict p);
there would be no standard way to pass a structure defined at the call site
without forcing sub-optimal code generation from any compiler that can't
see into the external function. For example, given:
void testThingie(void)
{
useThingie(&(struct foo){5});
}
a compiler that can't see into "useThingie" would need to create a new
variable on the stack and pass the address of that. By contrast, if the
code were written:
void testThingie(void)
{
static const struct fooFive = {5};
useThingie(&fooFive);
}
a compiler could simply pass a constant address to the function without
having to store the value 5 anywhere at runtime. Note that such a
substitution would not be available to a compiler which can't see into
useThingie, no matter how much the pointer qualifiers would seem to favor
it, since useThingie would be allowed to do something like:
static struct foo *oldP = 0;
void useThingie(struct foo const *restrict p)
{
if (!oldP)
{
oldP = p;
testThingie();
}
else
{
printf((oldP != p) ?
"Different variables for the two calls" :
"Same variable for the two calls");
oldP = 0;
}
}
and if it did so, it would be entitled to expect that within the nested
call, p and oldP would be different. No matter how unlikely it might seem
that useThingie would do such a thing, the Standard would require that
compilers pessimistically allow for such a possibility.
[toc] | [prev] | [next] | [standalone]
Page 3 of 6 — ← Prev page 1 2 [3] 4 5 6 Next page →
Back to top | Article view | comp.lang.c
csiph-web