using name_declared in if statement

Particularly useful chunks of hoc and/or NMODL code. May be pedestrian or stunningly brilliant, may make you gasp or bring tears to your eyes, but always makes you think "I wish I had written that; I'm sure going to steal it."
Post Reply
chris
Posts: 2
Joined: Mon Nov 23, 2015 9:30 am

using name_declared in if statement

Post by chris »

so I was testing some code when I came across a strange circumstance...
if I do

Code: Select all

if(name_declared("newvar")!=5){
 newvar = 10
}
newvar has a value of 0 after this code!
I am not really sure what is going on as anything inside the if statement does not seem to be executed, but newvar is "declared" (to 0).
So I can understand that if the if statement is false variables inside are put in the symbol table with default value of 0. But then why isn't the if statement true?

if I instead do this:

Code: Select all

type = name_declared("newvar")
if(type !=5){
 newvar = 10
}
newvar has a value of 10...

so how do the code blocks differ actually?

further, the behaviour is different in a procedure.
That is, every variable is in the symbol table immediately after the function is defined, but before the function can be called. So everything using name_declared within the procedure/function with a variable defined within the function is on a declared variable.

I know name_declared shouldn't often be used, but it is useful for testing a file with default/test values if it isn't loaded from another file.
And I know there are alternatives such as using Python, but I found this strange and wondered why...

some more test code:

Code: Select all

printf("declared a: %g\n",name_declared("a"))			// -> declared a: 0
printf("name_declared(a)!=5  %g\n",name_declared("a")!=5) // -> name_declared(a)!=5   1
type=name_declared("a")
if(type!=5){
	printf("in if a\n")		//-> prints
	a = 10
	printf("value: %g\n",a)	//-> prints
}
printf("declared a: %g, value: %g\n",name_declared("a"),a) //-> declared a: 5, value: 10

printf("declared b: %g\n",name_declared("b")) //-> declared b: 1
printf("name_declared(b)!=5  %g\n",name_declared("b")!=5) // -> name_declared(b)!=5   1
if(name_declared("b")!=5){
	printf("in if b\n")		// doesn't print
	b = 10
	printf("value: %g\n",b)	// doesn't print
}
printf("declared b: %g, value: %g\n",name_declared("b"),b)	//-> declared b: 5, value: 0

if(name_declared("c")!=5){
	printf("in if c\n") 	//doesn't print
	c = 10
	printf("declared c: %g, value: %g\n",name_declared("c"),c) //doesn't print
}

proc testProc(){
	printf("name_declare\n")
	printf("declared d: %g\n",name_declared("d"))			// -> declared d: 5
	printf("name_declared(d)!=5  %g\n",name_declared("d")!=5) // -> name_declared(d)!=5   0
	type=name_declared("d")
	if(type!=5){
		printf("in if d\n")		// doesn't print
		d = 10
		printf("value: %g\n",d)	// doesn't print
	}
	printf("declared d: %g, value: %g\n",name_declared("d"),d) //-> declared d: 5, value: 0

	printf("declared e: %g\n",name_declared("e")) //-> declared e: 1
	if(name_declared("e")!=5){
		printf("in if e\n")		// doesn't print
		e = 10
		printf("value: %g\n",e)	// doesn't print
	}
	printf("declared e: %g, value: %g\n",name_declared("e"),e)	//-> declared e: 5, value: 0

	if(name_declared("f")!=5){
		printf("in if f\n") 	//doesn't print
		f = 10
		printf("declared f: %g, value: %g\n",name_declared("f"),f) //doesn't print
	}
}
testProc()

hines
Site Admin
Posts: 1682
Joined: Wed May 18, 2005 3:32 pm

Re: using name_declared in if statement

Post by hines »

In your first fragment name became defined during parsing (default value of 0) of the "if" statement and then "name=10" was never executed.
The idiom to avoid this
if (name_declared("name") == 0) { execute("name = ...") }
then name becomes declared only when the execute statement is actually executed.
chris
Posts: 2
Joined: Mon Nov 23, 2015 9:30 am

Re: using name_declared in if statement

Post by chris »

Thanks!
Post Reply