June 30, 2004
In article <cbtqrd$1lhq$1@digitaldaemon.com>, Arcane Jill says...
>
>
>Not in reply to anyone in particular....
>
>In C and C++, the function:
>
>#    void f(int n) // unused parameter
>#    {
>#        (void) n; // note this line
>#    }
>
>will compile without error or warning, as I believe it should. That strange void line tells the compiler *I DON'T WANT TO USE THIS VARIABLE*.
>
>I'm in favor of unsused variables being a compile-error, unless explicitly indicated by the programmer, as above (or using some other, D-specific, syntax).
>
>Arcane Jill

An elegant solution.

Can I assume a similar void statement would also work outside the function, to discard an unwanted parameter?


June 30, 2004
In article <cbti1b$1765$1@digitaldaemon.com>, Walter says...
>
>
>"Rex Couture" <Rex_member@pathlink.com> wrote in message news:cbt6f5$l92$1@digitaldaemon.com...
>> In article <cbsfns$2n3g$1@digitaldaemon.com>, Walter says...
>> >I'll go with my experience implementing the C and C++ standards - it's better to conform to the standards. Fixing what I consider to be
>suboptimal
>> >decisions in those standards has turned out to be a failure.
>> I'm shocked.  Is this another C/C++ compiler?  I thought it was supposed
>to be
>> something better.
>
>Yup - here I was referring not to C/C++ in particular, but to my experience with the utility of implementing slightly non-standard compilers.

Oh.  Sorry, I misunderstood.


>> And pardon my ignorance, but as a mere mortal programmer, I haven't the slightest idea why
>>
>> #    if (a == b) a == c;
>>
>> should compile.  Sooner or later, someone is going to die over errors like
>that.
>
>If a==c actually calls a function opCmp, and one is writing code that wants to 'tickle' that function. This comes up sometimes in writing test coverage code, or in profiling code. This can also come up in generic code if one wants to verify that a and b are "comparable", but not care what the result is. It can also come up as the result of the combination of various optimizations and function inlining.

Pardon me.  I guess I'll have to defer to you on that one.


June 30, 2004
In article <cbti1b$1765$1@digitaldaemon.com>, Walter says...
>
>
>"Rex Couture" <Rex_member@pathlink.com> wrote in message news:cbt6f5$l92$1@digitaldaemon.com...
>> In article <cbsfns$2n3g$1@digitaldaemon.com>, Walter says...

Oh, and thanks for replying.  Sorry I didn't see your reply sooner.  There are a lot of messages here.  Some of my later messages are a little tart.


June 30, 2004
"Rex Couture" <Rex_member@pathlink.com> wrote in message news:cbtvc7$23pn$1@digitaldaemon.com...
> In article <cbti1b$1765$1@digitaldaemon.com>, Walter says...
> >
> >
> >"Rex Couture" <Rex_member@pathlink.com> wrote in message news:cbt6f5$l92$1@digitaldaemon.com...
> >> In article <cbsfns$2n3g$1@digitaldaemon.com>, Walter says...
>
> Oh, and thanks for replying.  Sorry I didn't see your reply sooner.  There
are a
> lot of messages here.  Some of my later messages are a little tart.

No worries. I'm at least a couple thousand messages behind :-(


July 02, 2004
Derek Parnell wrote:
> On Mon, 28 Jun 2004 12:49:56 -0700, Walter wrote:
> 
> In the code below, is the non-use of the function argument 'a' an error or
> not? If its an error then why does D allow it?
> 
> If its not an error, wouldn't it be 'nice' to inform the coder of a
> POTENTIAL error or not? 
> 
> # int foo(int a)
> # {
> #     return 1;
> # }
> # # void main( )
> # {
> #     printf("%d\n", foo(200));
> # }

Ok, I'm not going to take sides on the warning issue, because frankly I agree with both sides here.  But I am going to jump in and say that you could treat this as an error, and still handle the legitimate cases, if you had an 'expire' construct, that worked like this:



  int foo(int a)
  {
    expire a;
    return 1;
  }



'expire' would simply make a contract that a variable must not be used later in the function.  So, it would be an error to have a function which did not use one of its arguments - unless it explicitly expired them.  It is an explicit contract of "I don't care about this value."

Or, perhaps, maybe expire should be simply a statement that tells the compiler "pretend as though this is uninitialized data."  So try out this code:

  void bar(int b)
  {
    int arg_save = b;

    printf("Old value of b = %d\n", b);

    expire b;
    int a = b;	// SYNTAX ERROR, b is expired
    b = arg_save*arg_save;

    printf("New value of b = %d\n", b); // OK, b is valid again
  }



Thoughts?

July 02, 2004
On Thu, 01 Jul 2004 17:34:15 -0700, Russ Lewis wrote:

> Derek Parnell wrote:
>> On Mon, 28 Jun 2004 12:49:56 -0700, Walter wrote:
>> 
>> In the code below, is the non-use of the function argument 'a' an error or not? If its an error then why does D allow it?
>> 
>> If its not an error, wouldn't it be 'nice' to inform the coder of a POTENTIAL error or not?
>> 
>> # int foo(int a)
>> # {
>> #     return 1;
>> # }
>> #
>> # void main( )
>> # {
>> #     printf("%d\n", foo(200));
>> # }
> 
> Ok, I'm not going to take sides on the warning issue, because frankly I agree with both sides here.  But I am going to jump in and say that you could treat this as an error, and still handle the legitimate cases, if you had an 'expire' construct, that worked like this:
> 
>    int foo(int a)
>    {
>      expire a;
>      return 1;
>    }
> 
> 'expire' would simply make a contract that a variable must not be used later in the function.  So, it would be an error to have a function which did not use one of its arguments - unless it explicitly expired them.  It is an explicit contract of "I don't care about this value."
> 
> Or, perhaps, maybe expire should be simply a statement that tells the compiler "pretend as though this is uninitialized data."  So try out this code:
> 
>    void bar(int b)
>    {
>      int arg_save = b;
> 
>      printf("Old value of b = %d\n", b);
> 
>      expire b;
>      int a = b;	// SYNTAX ERROR, b is expired
>      b = arg_save*arg_save;
> 
>      printf("New value of b = %d\n", b); // OK, b is valid again
>    }
> 
> Thoughts?

I like this idea a lot. It is brief, explicit, permissive, parsible, and doesn't break any existing code.

-- 
Derek
Melbourne, Australia
2/Jul/04 10:39:43 AM
July 02, 2004
Regan Heath wrote:
> I think you should give Walter a chance to give you an example where you'd want to have an un-used parameter, I suspect the times you'd want one have all been solved by having default function parameters, see my post asking walter for examples, for an example if this.
> 
> To be fair an un-used parameter does not cause a crash, it might not cause the desired behaviour, as it's not being used to do whatever it is supposed to do, but, you should notice this either in a DBC out block OR in a unittest OR the first time you run your code.

After defining an API, you may change it in the future, and choose to ignore one or more arguments.  Or, consider the situation where you have an API which had different implementations.  Some of the implementations might make use of certain parameters which are ignored in other implementations.

July 02, 2004
On Thu, 01 Jul 2004 21:53:18 -0700, Russ Lewis <spamhole-2001-07-16@deming-os.org> wrote:

> Regan Heath wrote:
>> I think you should give Walter a chance to give you an example where you'd want to have an un-used parameter, I suspect the times you'd want one have all been solved by having default function parameters, see my post asking walter for examples, for an example if this.
>>
>> To be fair an un-used parameter does not cause a crash, it might not cause the desired behaviour, as it's not being used to do whatever it is supposed to do, but, you should notice this either in a DBC out block OR in a unittest OR the first time you run your code.
>
> After defining an API, you may change it in the future, and choose to ignore one or more arguments.

Don't you then end up with an API that does not behave the same as it used to?
i.e.

int doStuff(bool sort, bool interleave, bool capitalise) { .. }

if you start to ignore one or more of those, then the function will be doing either one or the other (sort or not sort ..etc..), and not what is specified.

> Or, consider the situation where you have an API which had different implementations.  Some of the implementations might make use of certain parameters which are ignored in other implementations.

In this case, unless you can choose the implementation then it's the same as above, you get different results and have no control over when/where so the API will be incosistent.

Basically if you start to ignore a parameter you change the behaviour, and that's bad.. right?

Do you have a specific example where it doesn't change the behaviour?

Regan.

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
July 02, 2004
On Fri, 02 Jul 2004 17:47:02 +1200, Regan Heath wrote:

> On Thu, 01 Jul 2004 21:53:18 -0700, Russ Lewis <spamhole-2001-07-16@deming-os.org> wrote:
> 
>> Regan Heath wrote:
>>> I think you should give Walter a chance to give you an example where you'd want to have an un-used parameter, I suspect the times you'd want one have all been solved by having default function parameters, see my post asking walter for examples, for an example if this.
>>>
>>> To be fair an un-used parameter does not cause a crash, it might not cause the desired behaviour, as it's not being used to do whatever it is supposed to do, but, you should notice this either in a DBC out block OR in a unittest OR the first time you run your code.
>>
>> After defining an API, you may change it in the future, and choose to ignore one or more arguments.
> 
> Don't you then end up with an API that does not behave the same as it used
> to?
> i.e.
> 
> int doStuff(bool sort, bool interleave, bool capitalise) { .. }
> 
> if you start to ignore one or more of those, then the function will be doing either one or the other (sort or not sort ..etc..), and not what is specified.
> 
>> Or, consider the situation where you have an API which had different implementations.  Some of the implementations might make use of certain parameters which are ignored in other implementations.
> 
> In this case, unless you can choose the implementation then it's the same as above, you get different results and have no control over when/where so the API will be incosistent.
> 
> Basically if you start to ignore a parameter you change the behaviour, and that's bad.. right?
> 
> Do you have a specific example where it doesn't change the behaviour?
> 
> Regan.

I have an real-world example where occasionally it is right to ignore a parameter.

I use a library that is a Windows GUI development tool (BTW, I must think about porting it to D) and the way it handles events is that the application sets up an event handler for a control/event combination. The library calls your event handler with exactly three parameters : The ID of the control the event happened to, the id of the event type, and a dynamic array of parameters specific to the event.

Not every event handler needs all this information, but it is given to each and every event handler. So frequently, the code in the event handler ignores one or more of the parameters supplied to it.

An example might be useful (not D code) ...

# procedure onMouse_Background(integer self, integer event, sequence parms)
#     sequence lDownData
#     if parms[1] = WM_LBUTTONDOWN then
#        -- Process the left down action
#        push({self, parms[2], parms[3]})
#     elsif parms[1] = WM_LBUTTONUP then
#        -- Process the left up action
#        lDownData = pop()
#        if lDownData[1] != self then
#            return
#        end if
#        if abs(lDownData[2] - parms[2]) < XTolerance and
#           abs(lDownData[3] - parms[3]) < YTolerance then
#            DrawTo(lDownData)
#        end if
#     end if
# end procedure
# -- Share the same event handler for both background areas.
# setHandler(BG_two, w32HMouse, routine_id("onMouse_Background"))
# setHandler(BG_one, w32HMouse, routine_id("onMouse_Background"))

Here the 'event' parameter is not needed even though it is supplied by the GUI library.

It would be nice to tell the compiler that I'm deliberately not using that parameter. The 'expire' idea would suffice.

-- 
Derek
Melbourne, Australia
2/Jul/04 3:53:09 PM
July 02, 2004
On Fri, 2 Jul 2004 16:17:39 +1000, Derek Parnell <derek@psych.ward> wrote:

> On Fri, 02 Jul 2004 17:47:02 +1200, Regan Heath wrote:
>
>> On Thu, 01 Jul 2004 21:53:18 -0700, Russ Lewis
>> <spamhole-2001-07-16@deming-os.org> wrote:
>>
>>> Regan Heath wrote:
>>>> I think you should give Walter a chance to give you an example where
>>>> you'd want to have an un-used parameter, I suspect the times you'd want
>>>> one have all been solved by having default function parameters, see my
>>>> post asking walter for examples, for an example if this.
>>>>
>>>> To be fair an un-used parameter does not cause a crash, it might not
>>>> cause the desired behaviour, as it's not being used to do whatever it
>>>> is supposed to do, but, you should notice this either in a DBC out
>>>> block OR in a unittest OR the first time you run your code.
>>>
>>> After defining an API, you may change it in the future, and choose to
>>> ignore one or more arguments.
>>
>> Don't you then end up with an API that does not behave the same as it used
>> to?
>> i.e.
>>
>> int doStuff(bool sort, bool interleave, bool capitalise) { .. }
>>
>> if you start to ignore one or more of those, then the function will be
>> doing either one or the other (sort or not sort ..etc..), and not what is
>> specified.
>>
>>> Or, consider the situation where you have an API which had different
>>> implementations.  Some of the implementations might make use of certain
>>> parameters which are ignored in other implementations.
>>
>> In this case, unless you can choose the implementation then it's the same
>> as above, you get different results and have no control over when/where so
>> the API will be incosistent.
>>
>> Basically if you start to ignore a parameter you change the behaviour, and
>> that's bad.. right?
>>
>> Do you have a specific example where it doesn't change the behaviour?
>>
>> Regan.
>
> I have an real-world example where occasionally it is right to ignore a
> parameter.
>
> I use a library that is a Windows GUI development tool (BTW, I must think
> about porting it to D) and the way it handles events is that the
> application sets up an event handler for a control/event combination. The
> library calls your event handler with exactly three parameters : The ID of
> the control the event happened to, the id of the event type, and a dynamic
> array of parameters specific to the event.
>
> Not every event handler needs all this information, but it is given to each
> and every event handler. So frequently, the code in the event handler
> ignores one or more of the parameters supplied to it.

Ahh.. yes, good example. :)
Regan

> An example might be useful (not D code) ...
>
> # procedure onMouse_Background(integer self, integer event, sequence parms)
> #     sequence lDownData
> #     if parms[1] = WM_LBUTTONDOWN then
> #        -- Process the left down action
> #        push({self, parms[2], parms[3]})
> #     elsif parms[1] = WM_LBUTTONUP then
> #        -- Process the left up action
> #        lDownData = pop()
> #        if lDownData[1] != self then
> #            return
> #        end if
> #        if abs(lDownData[2] - parms[2]) < XTolerance and
> #           abs(lDownData[3] - parms[3]) < YTolerance then
> #            DrawTo(lDownData)
> #        end if
> #     end if
> # end procedure
> # -- Share the same event handler for both background areas.
> # setHandler(BG_two, w32HMouse, routine_id("onMouse_Background"))
> # setHandler(BG_one, w32HMouse, routine_id("onMouse_Background"))
>
> Here the 'event' parameter is not needed even though it is supplied by the
> GUI library.
>
> It would be nice to tell the compiler that I'm deliberately not using that
> parameter. The 'expire' idea would suffice.
>



-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/