POV-Ray : Newsgroups : povray.general : Problem with parameters Server Time
11 Oct 2026 22:20:48 EDT (-0400)
  Problem with parameters (Message 1 to 22 of 22)  
From: Martin
Subject: Problem with parameters
Date: 26 Feb 2008 20:07:14
Message: <47c4b7c2$1@news.povray.org>
Hello. First of all, i serched with google on this site without seeing 
any mention to my problem. So, apologies if i am repeating.

I have something wrong in the following code, but i cannot see it. It 
pretends to be a minimun sample, and its only purpose is to show the 
problem. It occurs in a bigger file that i'm working on. At first, i 
tried to isolate the error there, but it was impossible to me (i am not 
a programmer :). Finally i could find what seems to be wrong.

//pov version: 3.6.1c.icl8.win32
//-------------------------------------------------------------
default{ pigment{rgb <1,1,0>} }

//this is ok, for control purposes
#macro Wave_Ctrl(N,Fr,A,Fs,L)
   #local C=0;
   #while(C < N)
     sphere{z*L*C/N+y*A*sin(2*pi*Fr*C/N+Fs) 0.05 pigment{red 1}}
     #local C= C+1;
   #end
#end
//Here starts the problem
//let's say i need some macros with parameters passed both, per value 
//and reference
#macro WavePt(pZ,pY)
   DoCalc(pZ,pY,cC,+cN) sphere{z*pZ+y*pY 0.05 }
#end

#macro DoCalc(pZ,pY,I,N) //function arbitrarily choosen
   #local pY= y*cA*sin(2*pi*cFr*I/N+cFs);
   #local pZ= z*L*I/N;
#end
//
#macro WrongWave(cN,Fr,A,Fs,L)
   #local cA= A; #local cFr= Fr; #local cFs= Fs;
   #local cC=0; #local pY=0*y; #local pZ=0*z;
   #while(cC < cN) WavePt(pY,pZ) #local cC= cC+1; #end
#end

#declare cN= 500;
#declare Freq= 5; #declare Amp= 0.5; #declare Phase=0; #declare L=10;

//#debug "doesn't matter what\n" //(1)
#declare Ctrl= no;
#local I=0; #local T= 50; #local cRt= 360/T;
#while(I < T)
   union{
     #if(!Ctrl)
       WrongWave(cN,Freq,Amp,Phase,L)
     #else
       Wave_Ctrl(cN,Freq,Amp,Phase,L)
     #end
     rotate y*cRt*I
   }
   #local I=I+1;
#end

The problem: while in the Wave_Ctrl() macro all the spheres are placed 
correctly, in the WrongWave() one, that it's supposed to do the same, 
some spheres are out of place. At first i thought in a rounding error, 
but as i never have faced one, i don't know what it looks like :/.

But if it is a rounding error, why Wave_Ctrl is rendering properly? and 
Why typing a debug line affects the resulting image (with WrongWave())? 
Uncomment the line (1) and probably the wrong placed spheres will 
change. Anyway, here i am not adding  or performing further operations 
with the resulting calculations, the counter is integer...

Maybe the sample seems a bit silly, but this problem ruins a scene where 
the objects has been calculated previously in size and position.

Thank you very much in advance

Martin


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Problem with parameters
Date: 26 Feb 2008 20:57:44
Message: <47c4c398@news.povray.org>
Martin wrote:
...
> #macro DoCalc(pZ,pY,I,N) //function arbitrarily choosen
>   #local pY= y*cA*sin(2*pi*cFr*I/N+cFs);
>   #local pZ= z*L*I/N;
> #end
...

Note that this macro should (AFAIK) have no effect in any scene.

If it has, then that might be a bug in the POV-Ray version you
are using.

(You are just setting 2 local variables that are "lost" right
afterwards when the macro is exited.)

-- 
Tor Olav
http://subcube.com


Post a reply to this message

From: Tim Attwood
Subject: Re: Problem with parameters
Date: 26 Feb 2008 23:56:21
Message: <47c4ed75$1@news.povray.org>
>> #macro DoCalc(pZ,pY,I,N) //function arbitrarily choosen
>>   #local pY= y*cA*sin(2*pi*cFr*I/N+cFs);
>>   #local pZ= z*L*I/N;
>> #end
> ...
>
> Note that this macro should (AFAIK) have no effect in any scene.
>
> If it has, then that might be a bug in the POV-Ray version you
> are using.
>
> (You are just setting 2 local variables that are "lost" right
> afterwards when the macro is exited.)

That isn't exactly right, pY and pZ are being returned by
parameter.

Unfortunately in 3.6 passing values by parameter is buggy,
it's fixed in the 3.7 beta, but in general you probably shouldn't
rely on values being returned correctly via parameter.

Typically you can either globally #declare a value to return,
or return a value by subsitution like this...

#macro DoCalcY(pZ,pY,I,N)
   #local result = y*cA*sin(2*pi*cFr*I/N+cFs);
   (result)
#end

#macro DoCalcZ(pZ,pY,I,N)
   #local result = z*L*I/N;
   (result)
#end

And call the calculations...

#local pY = DoCalcY(pZ,pY,I,N);
#local pZ = DoCalcZ(pZ,pY,I,N);


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Problem with parameters
Date: 27 Feb 2008 02:51:32
Message: <47c51684$1@news.povray.org>
Tim Attwood wrote:
>>> #macro DoCalc(pZ,pY,I,N) //function arbitrarily choosen
>>>   #local pY= y*cA*sin(2*pi*cFr*I/N+cFs);
>>>   #local pZ= z*L*I/N;
>>> #end
>> ...
>>
>> Note that this macro should (AFAIK) have no effect in any scene.
>>
>> If it has, then that might be a bug in the POV-Ray version you
>> are using.
>>
>> (You are just setting 2 local variables that are "lost" right
>> afterwards when the macro is exited.)
> 
> That isn't exactly right, pY and pZ are being returned by
> parameter.

How can it be wrong when his macro is not returning anything ?
(Note that he is using #local instead of #declare.)

I have re-read these to sections of the documentation;

   "2.2.2.2 The #declare and #local Directives"
   "2.2.2.8 User Defined Macros"

- without finding anything that about changing contents of
passed parameters within macros by using #local.

The 2 manual sections:

   http://www.povray.org/documentation/view/3.6.1/237/
   http://www.povray.org/documentation/view/3.6.1/243/

> Unfortunately in 3.6 passing values by parameter is buggy,
> it's fixed in the 3.7 beta, but in general you probably shouldn't
> rely on values being returned correctly via parameter.
...

Yes I know. Sometimes I have to use v3.5 to render my code.
(But I have never been able to make a simple scene file that
clearly demonstrates the problem.)

-- 
Tor Olav
http://subcube.com


Post a reply to this message

From: Tim Attwood
Subject: Re: Problem with parameters
Date: 27 Feb 2008 03:52:23
Message: <47c524c7$1@news.povray.org>
> How can it be wrong when his macro is not returning anything ?
> (Note that he is using #local instead of #declare.)

2.2.2.8.5 explains it a bit, if an identifier is passed to a
macro then that identifier is in scope and #local will
modify that identifier's value.

The return-by-parameter bug is more apparent in loops,
sometimes the modified value of a parameter isn't returned,
but that's less than 1% of the time, and it's fixed in 3.7 :-)

Try this test code to convince yourself that #local in
a macro can modify a parameter value.

#macro TEST(A)
   #local A = A + 1;
#end

#declare B = 1;

TEST(B)

text { // the answer is 2
   ttf "timrom.ttf",
   concat("B = ", str(B,0,0)), 0.1,0
   pigment {rgb <0,1,0>}
   finish {ambient 1}
   translate <-1,-0.2,2>
}


Post a reply to this message

From: Warp
Subject: Re: Problem with parameters
Date: 27 Feb 2008 04:57:24
Message: <47c53404@news.povray.org>
Tim Attwood <tim### [at] comcastnet> wrote:
> text { // the answer is 2
>    ttf "timrom.ttf",
>    concat("B = ", str(B,0,0)), 0.1,0
>    pigment {rgb <0,1,0>}
>    finish {ambient 1}
>    translate <-1,-0.2,2>
> }

  Wouldn't usually #debug be used for that? Easier.

-- 
                                                          - Warp


Post a reply to this message

From: Martin
Subject: Re: Problem with parameters
Date: 27 Feb 2008 09:33:12
Message: <47c574a8$1@news.povray.org>
Tim Attwood escribió:
> Unfortunately in 3.6 passing values by parameter is buggy,
> it's fixed in the 3.7 beta, but in general you probably shouldn't
> rely on values being returned correctly via parameter.
> 
Just for curiosity sake, do you mean in general programming, or only in 
SDL (and why)?

At the end, i read that a parameter (in programming) is just a variable 
stored in the stack (and recovered later).


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Problem with parameters
Date: 27 Feb 2008 09:56:58
Message: <47c57a3a@news.povray.org>
Martin escribió:
> Tim Attwood escribió:
>> Unfortunately in 3.6 passing values by parameter is buggy,
>> it's fixed in the 3.7 beta, but in general you probably shouldn't
>> rely on values being returned correctly via parameter.
>>
> Just for curiosity sake, do you mean in general programming, or only in 
> SDL (and why)?
> 
> At the end, i read that a parameter (in programming) is just a variable 
> stored in the stack (and recovered later).

That depends on the programming language. In C, you'd have to pass a 
pointer.

void change_param(int* foo) {
     *foo=42;
}
...
int bar = 1;
change_param(&bar);


Post a reply to this message

From: Darren New
Subject: Re: Problem with parameters
Date: 27 Feb 2008 11:51:17
Message: <47c59505$1@news.povray.org>
Warp wrote:
> Tim Attwood <tim### [at] comcastnet> wrote:
>> text { // the answer is 2
>>    ttf "timrom.ttf",
>>    concat("B = ", str(B,0,0)), 0.1,0
>>    pigment {rgb <0,1,0>}
>>    finish {ambient 1}
>>    translate <-1,-0.2,2>
>> }
> 
>   Wouldn't usually #debug be used for that? Easier.

That wouldn't be *shiny*!

-- 
   Darren New / San Diego, CA, USA (PST)
     "That's pretty. Where's that?"
          "It's the Age of Channelwood."
     "We should go there on vacation some time."


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Problem with parameters
Date: 27 Feb 2008 16:17:07
Message: <47c5d353$1@news.povray.org>
Tim Attwood wrote:
>> How can it be wrong when his macro is not returning anything ?
>> (Note that he is using #local instead of #declare.)
> 
> 2.2.2.8.5 explains it a bit, if an identifier is passed to a
> macro then that identifier is in scope and #local will
> modify that identifier's value.
> 
> The return-by-parameter bug is more apparent in loops,
> sometimes the modified value of a parameter isn't returned,
> but that's less than 1% of the time, and it's fixed in 3.7 :-)
> 
> Try this test code to convince yourself that #local in
> a macro can modify a parameter value.
> 
> #macro TEST(A)
>    #local A = A + 1;
> #end
> 
> #declare B = 1;
> 
> TEST(B)
...

Your code above may work, but was it meant to work that way ?
I.e. Is the behaviour above a bug - or is it a feature ?
:)

To me it is illogical that a #local statement should be
able to change _anything_ outside its scope.

Do you have any references to documentation, discussions
(or source code) that _clearly_ shows that one may use a
#local assignment to return a value by a parameter passed
to a macro ?

Section 2.2.2.8.5 in the manual shows #declare used to
change a given parameter in a macro.

-- 
Tor Olav
http://subcube.com


Post a reply to this message

From: Warp
Subject: Re: Problem with parameters
Date: 27 Feb 2008 16:40:12
Message: <47c5d8bc@news.povray.org>
Tor Olav Kristensen <tor### [at] toberemovedgmailcom> wrote:
> > #macro TEST(A)
> >    #local A = A + 1;
> > #end
> > 
> > #declare B = 1;
> > 
> > TEST(B)
> ...

> Your code above may work, but was it meant to work that way ?
> I.e. Is the behaviour above a bug - or is it a feature ?
> :)

> To me it is illogical that a #local statement should be
> able to change _anything_ outside its scope.

  OTOH, how should it behave?

  Macro parameters are passed "by reference". This means that you can
do this:

#macro TEST(A)
  #declare A = A+1;
#end

and it will modify the original identifier given as parameter.

  You want #local to not to modify the original identifier. So basically
you want #local to make a local copy of the identifier and modify only that.
But then all kinds of problematic situations may arise, for instance:

#macro TEST(A)
  #local A = A+1;
  #declare A = A+1;
#end

  Should the #declare modify the local copy or the original identifier?

  More importantly: There are two A's now, the original and the local copy.
Which 'A' should be used in the right-hand-side of the '=' of the #declare,
the local copy or the original variable? If the #local only modifies a copy,
then this "local A" will have a different value than the original identifier.

-- 
                                                          - Warp


Post a reply to this message

From: Tim Attwood
Subject: Re: Problem with parameters
Date: 27 Feb 2008 19:09:05
Message: <47c5fba1$1@news.povray.org>
>> Unfortunately in 3.6 passing values by parameter is buggy,
>> it's fixed in the 3.7 beta, but in general you probably shouldn't
>> rely on values being returned correctly via parameter.
>>
> Just for curiosity sake, do you mean in general programming, or only in 
> SDL (and why)?

I meant just for POV SDL, passing values by parameter is the
norm in some languages, and passing values around in global
variables is considered bad form in most languages.

> At the end, I read that a parameter (in programming) is just a variable 
> stored in the stack (and recovered later).

Yeah, an identifier associates the variable name with a location
in memory which contains a value.  In POV a macro can be
passed an identifier, so that associates the parameter name
with the identifier name and location in memory.

Most programming languages don't have different versions
of variable assignment, the scope of a variable is usually
determined by the location it was created.


Post a reply to this message

From: Martin
Subject: Re: Problem with parameters
Date: 28 Feb 2008 09:07:52
Message: <47c6c038$1@news.povray.org>
Nooow works with 3.7 beta :). It happens that i always wait until the 
official release is finished.

Thanks again to all, and pleased to meet you

Martín.


Post a reply to this message

From: Jan Dvorak
Subject: Re: Problem with parameters
Date: 28 Feb 2008 11:06:18
Message: <47c6dbfa@news.povray.org>
Warp napsal(a):
> Tor Olav Kristensen <tor### [at] toberemovedgmailcom> wrote:
>>> #macro TEST(A)
>>>    #local A = A + 1;
>>> #end
>>>
>>> #declare B = 1;
>>>
>>> TEST(B)
>> ...
> 
>> Your code above may work, but was it meant to work that way ?
>> I.e. Is the behaviour above a bug - or is it a feature ?
>> :)
> 
>> To me it is illogical that a #local statement should be
>> able to change _anything_ outside its scope.
> 
>   OTOH, how should it behave?
> 
>   Macro parameters are passed "by reference". This means that you can
> do this:
> 
> #macro TEST(A)
>   #declare A = A+1;
> #end
> 
> and it will modify the original identifier given as parameter.
> 
>   You want #local to not to modify the original identifier. So basically
> you want #local to make a local copy of the identifier and modify only that.
> But then all kinds of problematic situations may arise, for instance:
> 
> #macro TEST(A)
>   #local A = A+1;
>   #declare A = A+1;
> #end
> 
>   Should the #declare modify the local copy or the original identifier?
> 
>   More importantly: There are two A's now, the original and the local copy.
> Which 'A' should be used in the right-hand-side of the '=' of the #declare,
> the local copy or the original variable? If the #local only modifies a copy,
> then this "local A" will have a different value than the original identifier.
> 
The specs says #local always creates the most local variable possible 
while #declare writes to the most local existing one. The most local 
existing one will be parsed.

-- 
the ultimate time-killer:
+a0.0 +am2 +r9

Johnny D


Post a reply to this message

From: Jan Dvorak
Subject: Re: Problem with parameters
Date: 28 Feb 2008 11:14:57
Message: <47c6de01$2@news.povray.org>
> Yeah, an identifier associates the variable name with a location
> in memory which contains a value.  In POV a macro can be
> passed an identifier, so that associates the parameter name
> with the identifier name and location in memory.
> 
> Most programming languages don't have different versions
> of variable assignment, the scope of a variable is usually
> determined by the location it was created. 
> 
> 

In Java you can declare a variable in a block (the most usual usage is 
for(int i=0;i<x.length;i++){..}) or a function, which is then the one to 
be used. To access the class variable you use this.var. To access the 
superclass variable/method instead you call super.var. A variable is 
local to the class/method/block it was declared in.
-- 
the ultimate time-killer:
+a0.0 +am2 +r9

Johnny D


Post a reply to this message

From: Tor Olav Kristensen
Subject: Re: Problem with parameters
Date: 28 Feb 2008 21:33:23
Message: <47c76ef3@news.povray.org>
Warp wrote:
> Tor Olav Kristensen <tor### [at] toberemovedgmailcom> wrote:
>>> #macro TEST(A)
>>>    #local A = A + 1;
>>> #end
>>>
>>> #declare B = 1;
>>>
>>> TEST(B)
>> ...
> 
>> Your code above may work, but was it meant to work that way ?
>> I.e. Is the behaviour above a bug - or is it a feature ?
>> :)
> 
>> To me it is illogical that a #local statement should be
>> able to change _anything_ outside its scope.
> 
>   OTOH, how should it behave?
> 
>   Macro parameters are passed "by reference". This means that you can
> do this:
> 
> #macro TEST(A)
>   #declare A = A+1;
> #end
> 
> and it will modify the original identifier given as parameter.
> 
>   You want #local to not to modify the original identifier. So basically
> you want #local to make a local copy of the identifier and modify only that.
> But then all kinds of problematic situations may arise, for instance:
> 
> #macro TEST(A)
>   #local A = A+1;
>   #declare A = A+1;
> #end
> 
>   Should the #declare modify the local copy or the original identifier?
> 
>   More importantly: There are two A's now, the original and the local copy.
> Which 'A' should be used in the right-hand-side of the '=' of the #declare,
> the local copy or the original variable? If the #local only modifies a copy,
> then this "local A" will have a different value than the original identifier.

I see the problem.

(So if this is meant as a feature, it would be nice if the
documentation describes more in detail what effect #local has
on macro parameters.)

Maybe a solution could be to have only one assignment
directive (e.g. #set or #let or none) and let call-by-value
be the default for parameters to macros. call-by-reference
could be indicated by e.g. "var" in the macro declaration.

   #macro TEST(A, var B)
     #set A = A + 1;
     #set B = B + A;
   #end

   #set C = 1;
   #set D = 3;

   TEST(C, D)
   // C is still 1. D has been changed to 5.

Another possibility could be to use "in", "out" and "in out"
in front of the parameters, like in Ada.

http://www.csc.liv.ac.uk/~grant/Teaching/COMP205/paramPassing.html

-- 
Tor Olav
http://subcube.com


Post a reply to this message

From: Warp
Subject: Re: Problem with parameters
Date: 29 Feb 2008 03:19:16
Message: <47c7c004@news.povray.org>
Tor Olav Kristensen <tor### [at] toberemovedgmailcom> wrote:
> Maybe a solution could be to have only one assignment
> directive (e.g. #set or #let or none) and let call-by-value
> be the default for parameters to macros.

  That would make the already-slow macros even slower, especially for
larger identifier types...

-- 
                                                          - Warp


Post a reply to this message

From: Tim Attwood
Subject: Re: Problem with parameters
Date: 29 Feb 2008 07:32:52
Message: <47c7fb74$1@news.povray.org>
>> Maybe a solution could be to have only one assignment
>> directive (e.g. #set or #let or none) and let call-by-value
>> be the default for parameters to macros.
>
>  That would make the already-slow macros even slower, especially for
> larger identifier types...

We could add a specific return command for passing values
by parameter...

#macro foobar(A, B)
   #return A = foo;
   #return B = bar;
#end

Not sure if that's a whole lot better though.


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Problem with parameters
Date: 29 Feb 2008 09:08:52
Message: <47c811f4$1@news.povray.org>
Warp escribió:
> Tor Olav Kristensen <tor### [at] toberemovedgmailcom> wrote:
>> Maybe a solution could be to have only one assignment
>> directive (e.g. #set or #let or none) and let call-by-value
>> be the default for parameters to macros.
> 
>   That would make the already-slow macros even slower, especially for
> larger identifier types...

What about copy on write?


Post a reply to this message

From: Warp
Subject: Re: Problem with parameters
Date: 29 Feb 2008 11:07:54
Message: <47c82dd9@news.povray.org>
Tim Attwood <tim### [at] comcastnet> wrote:
> We could add a specific return command for passing values
> by parameter...

> #macro foobar(A, B)
>    #return A = foo;
>    #return B = bar;
> #end

  I have a much simpler suggestion: If you don't want to modify an identifier
given as parameter, don't assign anything to it. It's that simple.

  If you need a copy of the identifier, then copy it:

#macro foobar(A)
{
  #local LocalCopyOfA = A;
  ...
}

  No need to make the SDL parser any more complicated than it already is.

-- 
                                                          - Warp


Post a reply to this message

From: Warp
Subject: Re: Problem with parameters
Date: 29 Feb 2008 11:40:39
Message: <47c83587@news.povray.org>
Nicolas Alvarez <nic### [at] gmailisthebestcom> wrote:
> What about copy on write?

  What about simply not assigning anything to the parameter if you don't
want to modify it?

-- 
                                                          - Warp


Post a reply to this message

From: Tim Attwood
Subject: Re: Problem with parameters
Date: 29 Feb 2008 18:24:22
Message: <47c89426$1@news.povray.org>
>  What about simply not assigning anything to the parameter if you don't
> want to modify it?

Nothing's wrong with how it is now, maybe the docs
could be changed to reflect that #local can be used
to pass values by parameter to avoid this kind of
confusion.


Post a reply to this message

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