Home AMX User Forum AMX Technical Discussion
Options

FUNCTION FAILS TO RETURN VALUE

I've spent the last several hours trying to get a function I've written to work. The function is defined to return an integer to the calling code. It also is recursive, and my first attempt at recursion. I focused most of my troubleshooting on the recursive nature, but now after reading posts on the behavior of Local_Vars vs. Static_Vars, I've concluded it's a variable scope issue.

Here's a outline of the original function and a button_event that called it. This approach failed in that the return value always turned out to be 0 so that nLOC_ZNE was 0.
DEFINE_FUNCTION INTEGER fnDO_THINGS(INTEGER nNUM)
{
	STACK_VAR INTEGER nRET
	LOCAL_VAR INTEGER nREC
	
	SWITCH(nNUM)
	{
		CASE 1:
		CASE 2:
		CASE 3:
		{
			RETURN nNUM
		}
		
		CASE 21:
		CASE 22:
		CASE 23:
		{
			nREC = nNUM -20
			fnDO_THINGS(nREC)
		}
		
		CASE 41:
		CASE 42:
		CASE 51:
		CASE 52:
		{
			RETURN nNUM
		}
	}
}

BUTTON_EVENT[dvTP,nSRC_BTNS]
{
	PUSH:
	{
		LOCAL_VAR INTEGER nINDX
		LOCAL_VAR INTEGER nLOC_ZNE
		
		nINDX = GET_LAST(nSRC_BTNS)
		nLOC_ZNE = fnDO_THINGS(nINDX)
	}
}

I tried changing local_var's to stack_vars among other things, but never got the function to return the correct (and non-zero, in this case) value.

I did get it work by creating a global variable and having the function act on that variable, as in the following:
DEFINE_VARIABLE
	INTEGER nNUMBER


DEFINE_FUNCTION INTEGER fnDO_THINGS(INTEGER nNUM)
{
	STACK_VAR INTEGER nRET
	LOCAL_VAR INTEGER nREC
	
	SWITCH(nNUM)
	{
		CASE 1:
		CASE 2:
		CASE 3:
		{
			nNUMBER = nNUM
		}
		
		CASE 21:
		CASE 22:
		CASE 23:
		{
			nREC = nNUM -20
			fnDO_THINGS(nREC)
		}
		
		CASE 41:
		CASE 42:
		CASE 51:
		CASE 52:
		{
			nNUMBER = nNUM
		}
	}
}

BUTTON_EVENT[dvTP,nSRC_BTNS]
{
	PUSH:
	{
		LOCAL_VAR INTEGER nINDX
		LOCAL_VAR INTEGER nLOC_ZNE
		
		nINDX = GET_LAST(nSRC_BTNS)
		fnDO_THINGS(nINDX)
		nLOC_ZNE = nNUMBER
	}
}
So in the above, the function modifies the global variable nNUMBER rather than returning the value.

This defeats one of the reasons to use a function.

Maybe some sharp eyes and more experienced ones can help me understand why the return approach failed.

Thanks
Rich Abel
Cello Technologies

Comments

  • Options
    Spire_JeffSpire_Jeff Posts: 1,917
    It's getting rather late for me, but try this:
    DEFINE_FUNCTION INTEGER fnDO_THINGS(INTEGER nNUM)
    {
    	STACK_VAR INTEGER nRET
    	LOCAL_VAR INTEGER nREC
    	
    	SWITCH(nNUM)
    	{
    		CASE 1:
    		CASE 2:
    		CASE 3:
    		{
    			RETURN nNUM
    		}
    		
    		CASE 21:
    		CASE 22:
    		CASE 23:
    		{
    			nREC = nNUM -20
    			RETURN fnDO_THINGS(nREC)
    		}
    		
    		CASE 41:
    		CASE 42:
    		CASE 51:
    		CASE 52:
    		{
    			RETURN nNUM
    		}
    	}
    }
    
    I'm not sure that will do what you want, but it may solve your problem of not getting a return value.

    Jeff
  • Options
    HedbergHedberg Posts: 671
    It seems to me that if you enter the function with either nindx = 3 or nindx = 52, the function returns the expected value. IF you call function with nindx = 23, the function cals itself recursively with nrec = 3 and will return the value 3 to the calling function (the first instance) but there appears to be no way to return that value to the button_event which called the first instance of the function. Jeffs solution takes the 3 returned be the recursive function call and returns it to the calling button_event. Joy.
  • Options
    mpullinmpullin Posts: 949
    Maybe this problem is solved, but in the future you should add a default case to your switch, this will trap everything that is not one of your cases. Also sprinkle SEND_STRING 0s around as a diagnostic technique. Cheers.
    DEFINE_FUNCTION INTEGER fnDO_THINGS(INTEGER nNUM)
    {
    	STACK_VAR INTEGER nRET
    	LOCAL_VAR INTEGER nREC
    	
    	SWITCH(nNUM)
    	{
    		CASE 1:
    		CASE 2:
    		CASE 3:
    			RETURN nNUM; BREAK;
    		CASE 21:
    		CASE 22:
    		CASE 23:
    			nREC = nNUM -20;
    			RETURN fnDO_THINGS(nREC); BREAK;
    		CASE 41:
    		CASE 42:
    		CASE 51:
    		CASE 52:
    			RETURN nNUM; BREAK;
    		DEFAULT:
    			SEND_STRING 0, "'Unexpected value ',itoa(nNUM)";
    			RETURN nNUM; BREAK;
    	}
    	SEND_STRING 0, 'Hey how did we get out here??';
    	SEND_STRING 0, 'Who cares, RUN FOR IT!!!!';
    	RETURN 0;
    }
    
  • Options
    jjamesjjames Posts: 2,908
    Shouldn't it be?
    DEFINE_FUNCTION INTEGER fnDO_THINGS(INTEGER nNUM)
    {
    	STACK_VAR INTEGER nRET
    	LOCAL_VAR INTEGER nREC
    	
    	SWITCH(nNUM)
    	{
    		CASE 1:
    		CASE 2:
    		CASE 3:
    			{RETURN nNUM; BREAK;}
    		CASE 21:
    		CASE 22:
    		CASE 23:
                   {
    			nREC = nNUM -20;
    			RETURN fnDO_THINGS(nREC); BREAK;
                   }
    		CASE 41:
    		CASE 42:
    		CASE 51:
    		CASE 52:
    			{RETURN nNUM; BREAK;}
    		DEFAULT:
                    {
    			SEND_STRING 0, "'Unexpected value ',itoa(nNUM)";
    			RETURN nNUM; BREAK;
                    }
    	}
    	SEND_STRING 0, 'Hey how did we get out here??';
    	SEND_STRING 0, 'Who cares, RUN FOR IT!!!!';
    	RETURN 0;
    }
    

    Note brackets.
  • Options
    Rich AbelRich Abel Posts: 104
    return value from function with recursion

    Jeff nailed it.

    I guess I niavely thought that the return value would 'find its way' back to the calling code.

    It did cause me to read the various threads on scope of variables, stack vs. local variables, etc, which will cause me to pay more attention to something I hadn't really given much thought to in the past.

    As always, thanks. I'd be lost without information and assistance from the forum....
  • Options
    mpullinmpullin Posts: 949
    jjames wrote: »
    Shouldn't it be?
    No, it sha'nt. :)

    Brackets aren't necessary for a case. Technically, the BREAKs aren't either, but they are needed in other languages to keep from dropping down into the next group of cases, so I use them anyway.
  • Options
    jjamesjjames Posts: 2,908
    mpullin wrote: »
    No, it sha'nt. :)
    Hmm . . . ok. I thought braces were needed for multi-lined IFs, ELSEs, ACTIVEs, CASEs, etc.

    I guess ya learn something new everyday! :D
Sign In or Register to comment.