POV-Ray : Newsgroups : povray.general : A painful lesson regarding function arguments. u=x, v=y. : Re: A painful lesson regarding function arguments. u=3D3Dx, v=3D3Dy. Server Time
21 May 2022 15:24:28 EDT (-0400)
  Re: A painful lesson regarding function arguments. u=3D3Dx, v=3D3Dy.  
From: William F Pokorny
Date: 30 Sep 2021 06:33:10
Message: <61559266$1@news.povray.org>
On 9/29/21 7:32 PM, Bald Eagle wrote:
> I thought it might be amusing and instructive to write a function that really
> mixes up the synonymous argument names, and maybe using ones not invoked in the
> function call - have you tried that experiment?
>> I think it'd be better to flag these argument issues as a problems
>> during parsing, but I'm not sure at the moment how to do it.
> When an argument gets tokenized, can you flag it as "set", and then issue a
> warning when it gets tokenized again that the previous value is being
> overwritten?  
(Maybe - for some situations)

As to your first question (no). I just tried this in the povr branch:

#declare Fn00 = function (x,y,u,z,y,x,z) { f_boom(x,y,z,u,v,0) }
#declare Fn01 = Fn00(1,2,3,4,5,6,7);


1(x) -> 6,
2(y) -> 5,
3(z) -> 7,
4(0) -> 6,
5(1) -> 5,
6(2) -> 0


The last out of order x, sets x and u in the function body.

The last y sets v which is not in the argument list, but where the v is 
used in the body of Fn00(AA).

The last z set is used, making the whole x,y,z,u,v set a - last one set 
wins collection - where x,u and y,v are aliases for each other.

(AA) Which led me to try:
#declare Fn00 = function (a,a,a,a,a,a,a) { f_boom(x,y,z,u,v,a) }
#declare Fn01 = Fn00(1,2,3,4,5,6,7);

which generates:

1(x) -> 0,
2(y) -> 0,
3(z) -> 0,
4(0) -> 0,
5(1) -> 0,
6(2) -> 1

which highlights another kind of trap! Namely, using z,y,z,u or v 
internal to a function body where you've not specified them in the 
argument list. Looks like those all default to 0 and the variables are 
available within the function body without complaint from the parser 
whether they are getting set by some explicit (or defaulted) argument 
passing or not. The 'not' case being the exposure.

With this:

#declare Fn00 = function (a) { f_boom(x,y,z,u,v,a) }
#declare Fn01 = Fn00(1);

The 'a' ends up set to 1 in the body and again all of x,y,z,u,v are 
available in the body and set to 0.

Yep, some parse time checks would be good. This all has me wondering how 
often I've fallen into one of these traps over the years and not known 
it. The episodes where I get frustrated and toss a whole set of 
functions in the trash bin and start completely anew - because I cannot 
'see' the issue with what I'd coded.

Aside: The argument duplicate defaulting for macros isn't the first set 
as is happening with 'a' above, but last one set. With the function 
arguments I believe by the time the parsing sees the second 'a' it 
understand it to be a value - there is already an entry in the local 
symbol hash table for 'a'. So, for any after the first, it substitutes 
the value it knows 'a' to be.

> PS
> I would also like to see some warnings on vector expansion, since missing a
> comma often inadvertently sends a 2-component vector to the parser rather than
> the intended 3-component one.
> <2, -3, 0> might be coded as <2 -3, 0>, leading to <-1, 0> which then gets
> expanded.

Yes, that one has gotten me a few times too.

Thinking aloud, with this kind of stuff, might well be a stand alone SDL 
linter utility would be easier to implement. Static code analysis for 
SDL! :-o

Bill P.

Post a reply to this message

Copyright 2003-2021 Persistence of Vision Raytracer Pty. Ltd.