Home AMX User Forum AMX Technical Discussion

Can a function return an array?

I can't get one to.
This compiles...
DEFINE_VARIABLE
LONG ar2[12][12]

DEFINE_FUNCTION LONG[12][12] array_test()
{
    LONG ar1[12][12]
    INTEGER bleh; INTEGER bar
    
    for(bar=1;bar<=12;bar++)
    {
	for(bleh = 1; bleh <=12; bleh++)
	{
	    ar1[bar][bleh] = bleh
	}
    }
    RETURN ar1
}

BUTTON_EVENT[dvTP, 1]
{
    PUSH:
    {
	ar2 = array_test()
    }
}


Line 68 (17:12:24):: GetVariableSize - Error Tk=0x0100
Line 69 (17:12:34):: GetString - Error 1 Tk=0x0000
Line 70 (17:12:34):: CopyString (Reference) - Error 2 S=0x0000 D=0x1033
Line 71 (17:12:34):: GetString - Error 1 Tk=0x0000
Line 72 (17:12:34):: CopyString (Reference) - Error 2 S=0x0000 D=0x1033

Comments

  • viningvining Posts: 4,368
    travis wrote: »
    I can't get one to.
    This compiles...
    DEFINE_VARIABLE
    LONG ar2[12][12]
    
    DEFINE_FUNCTION LONG[12][12] array_test()
    {
        LONG ar1[12][12]
        INTEGER bleh; INTEGER bar
        
        for(bar=1;bar<=12;bar++)
        {
    	for(bleh = 1; bleh <=12; bleh++)
    	{
    	    ar1[bar][bleh] = bleh
    	}
        }
        RETURN ar1
    }
    
    BUTTON_EVENT[dvTP, 1]
    {
        PUSH:
        {
    	ar2 = array_test()
        }
    }
    


    Line 68 (17:12:24):: GetVariableSize - Error Tk=0x0100
    Line 69 (17:12:34):: GetString - Error 1 Tk=0x0000
    Line 70 (17:12:34):: CopyString (Reference) - Error 2 S=0x0000 D=0x1033
    Line 71 (17:12:34):: GetString - Error 1 Tk=0x0000
    Line 72 (17:12:34):: CopyString (Reference) - Error 2 S=0x0000 D=0x1033

    I don't like this semi colon:
     INTEGER bleh; INTEGER bar
    
    the semi colon after bleh means INTEGER bar isn't being defined which breaks the code. Otherwise it should work I think since the help files say only structures and class (class?) won't work.
  • PhreaKPhreaK Posts: 966
    Short answer in your situation: nope.

    You can return an array but its limited to a single dimension. See [thread=5843]this thread[/thread].

    @vining
    The compiler treats the semi colon's as a statement terminator so it shouldn't be causing any issues.
  • viningvining Posts: 4,368
    PhreaK wrote: »
    Short answer in your situation: nope.

    You can return an array but its limited to a single dimension. See [thread=5843]this thread[/thread].

    @vining
    The compiler treats the semi colon's as a statement terminator so it shouldn't be causing any issues.

    I guess you're right. I was thinking end of line termination and I know it's screwed me up after function definition but if I took the time to look at the for loop in the code I would have easily realized my thoughtless observation couldn't possibly be correct.
  • ericmedleyericmedley Posts: 4,177
    I suppose you could kluge something by breaking up the array cells into single integers and then rebuild the return down in code.

    As long as the array isn't too big...
  • Joe HebertJoe Hebert Posts: 2,159
    Since all variables are passed by reference you can pass the variable in as a parameter and let the function fill it in.

    There are several Netlinx functions that use this technique such as ASTRO_CLOCK, FILE_DIR, FILE_READ, and GET_IP_ADDRESS to name a few.

    You can then use the RETURN value as some sort of pass or fail flag if so desired.
  • travistravis Posts: 180
    You can return an array but its limited to a single dimension. See this thread.

    Ah thanks. I didn't see this one in my searches.

    Also not a fan of the pass by reference way, especially when I'm trying to keep the function in an include instead of the main.

    Edit:
    Modules can pass multi-dimensional arrays. Re-usability crisis averted...
  • Joe HebertJoe Hebert Posts: 2,159
    travis wrote: »
    Also not a fan of the pass by reference way, especially when I'm trying to keep the function in an include instead of the main.
    It makes no difference if the function is inside an include instead of main.

    To make your test example work correctly...

    Change this:
    DEFINE_VARIABLE
    
    LONG ar2[12][12]
    
    [b]DEFINE_FUNCTION LONG[12][12] array_test()[/b]
    {
        [color=red]LONG ar1[12][12][/color]
        INTEGER bleh; INTEGER bar
        
        for(bar=1;bar<=12;bar++)
        {
    	for(bleh = 1; bleh <=12; bleh++)
    	{
    	    ar1[bar][bleh] = bleh
    	}
        }
        [color=red]RETURN ar1[/color]
    }
    
    DEFINE_EVENT
    
    BUTTON_EVENT[dvTP, 1]
    {
        PUSH:
        {
    	[b]ar2 = array_test()[/b]
        }
    }
    

    To this:
    DEFINE_VARIABLE
    
    LONG ar2[12][12]
    
    [b]DEFINE_FUNCTION array_test(LONG ar1[][])[/b]
    {
        INTEGER bleh; INTEGER bar
        
        for(bar=1;bar<=12;bar++)
        {
    	for(bleh = 1; bleh <=12; bleh++)
    	{
    	    ar1[bar][bleh] = bleh
    	}
        }
    }
    
    DEFINE_EVENT
    
    BUTTON_EVENT[dvTP, 1]
    {
        PUSH:
        {
    	[b]array_test(ar2)[/b]
        }
    }
    

    After you press button 1 each of the 12 rows in ar2 will be filled with the numbers 1-12.

    You can move the array_test() function to any include file that you want and it will work the same way.

    Tech Note 662 (SPLIT_STRING) is another example of a function that fills in a double dimensioned container that is passed into it.

    HTH
  • travistravis Posts: 180
    Thanks. Maybe I'm just being a little picky about the variable being defined in main instead in the include, so I can name it differently depending on what it's for. For example, the thing I'm working onis a CSV parser, and I'd like to be able to do something like

    room1 = parse_csv('room1.csv')
    foo = parse_csv('foo.csv')

    where parse_csv returns a two dimension array

    I could like you say above and just let the include complain about the variable not being defined; It still works, but that compiler warning bugs me.

    parse_csv('foo.csv', foo)
  • Joe HebertJoe Hebert Posts: 2,159
    Sorry, I’m not following you. If a variable is not defined that should be an error not a warning and it shouldn’t even compile.

    Your original function that I modified can be placed anywhere, in any include or in main. There shouldn’t be any kind of scope issue. There shouldn’t be any warnings or errors. I too am dead set against warnings and I won’t accept them.

    If you can give a more specific example I’d be happy to look at it. Or if you just want to drop it that’s fine too.

    Bottom line though, a function can *return* a double dimensioned array as SPLIT_STRING demonstrates. It just can’t be the RETURN value but it will accomplish the same exact thing.

    travis wrote: »
    Thanks. Maybe I'm just being a little picky about the variable being defined in main instead in the include, so I can name it differently depending on what it's for. For example, the thing I'm working onis a CSV parser, and I'd like to be able to do something like

    room1 = parse_csv('room1.csv')
    foo = parse_csv('foo.csv')

    where parse_csv returns a two dimension array

    I could like you say above and just let the include complain about the variable not being defined; It still works, but that compiler warning bugs me.

    parse_csv('foo.csv', foo)
  • travistravis Posts: 180
    Joe Hebert wrote: »
    Sorry, I’m not following you. If a variable is not defined that should be an error not a warning and it shouldn’t even compile.

    Your original function that I modified can be placed anywhere, in any include or in main. There shouldn’t be any kind of scope issue. There shouldn’t be any warnings or errors. I too am dead set against warnings and I won’t accept them.

    Sorry. I see what you're saying now. For some reason I thought the variables (the global and the function's) had to have the same name, but you used ar2 and ar1. That'll work fine then.

    But yeah, if you leave a variable name out of an include that needs it somewhere, it won't compile, but if you have that variable defined in your main, your main will compile, including the stuff in the include.
Sign In or Register to comment.