|
From: | Frank Swarbrick |
Subject: | Re: [open-cobol-list] procedure division returning |
Date: | Sun, 30 Jun 2013 20:40:34 -0600 |
User-agent: | Mozilla/5.0 (Windows NT 6.1; WOW64; rv:17.0) Gecko/20130509 Thunderbird/17.0.6 |
Hi Sergey,
That works in a limited fashion, but still has some issues. Issue #1: 14.1 Procedure division structure 14.1.1 General format where procedure-division-header is: PROCEDURE DIVISION [ using-phrase ] [ RETURNING data-name-2 ] 14.1.2 Syntax rules 5) Data-name-2 shall be defined as a level 01 entry or level 77 entry in the linkage section. ("in the linkage section" highlighted by me) With your change the returning data item must be in the working-storage section. (It doesn't even work if declared in the local-storage section.) I've been looking at how IBM mainframe COBOL solves this issue. It appears that if the returning data item is a non-group item the compiler automatically allocates stack storage for it (within the called routine) and then, in essence, does a "return" of that. Seems like a reasonable way to do it. Now if the returning data-item is a group data item, array, or string (really any item that cannot be returned in a register), the caller implicitly passes a reference to the return item as parameter 1, and the callee directly modifies the value at that location. So, basically, the following two statements function in the same manner: call 'callee' using by reference string-out string-in call 'callee' using by reference string-in returning string-out similarly, these are the same: program-id. 'callee'. data division. linkage section. 01 output-string display pic x(80). 01 input-string display pic x(80). procedure division using by reference output-string, input-string. move function reverse(input-string) to output-string exit program. program-id. 'callee'. data division. linkage section. 01 output-string display pic x(80). 01 input-string display pic x(80). procedure division using by reference input-string returning output-string. move function reverse(input-string) to output-string exit program. and a C call to either would be something like this: char output_string[80], input_string[80]; callee(output_string, input_string); if the parms were structs the call would be something like callee_struct(&out_struct, &in_struct); I got a little sidetracked on the second point, but the first point has another issue. It seems only to work with integer (comp/binary) parameters, but not with float/double (float-short, float-long) parameters. See the following example: local-storage section. 77 double-in comp-2 value 2. 77 double-out comp-2. call static 'cobatan2' using value double-in returning double-out /* Line: 18 : CALL : ret_test2.cob */ { { module.cob_procedure_params[0] = (f_5.data = "" + 0, &f_5); memset (&(module.cob_procedure_params[1]), 0, 32); cob_glob_ptr->cob_call_params = 1; (*(int *) (b_1)) = cobatan2 (*(double *)(cob_local_ptr + 0)); cob_set_int ((f_6.data = "" + 16, &f_6), (*(int *) (b_1))); } } Here the input parameter is properly cast to a pointer to a double, but the return value is treated as a pointer to an integer. I'm not at all sure, but I would imagine the last lines should be something to the effect of this: (*(double *) (b_1)) = cobatan2 (*(double *)(cob_local_ptr + 0)); cob_set_double ((f_6.data = "" + 16, &f_6), (*(double *) (b_1))); And of course b_1, which is the "return-code special register" needs to be large enough to hold a double (8 bytes instead of 4). Or use the actual variable directly. Are you by chance able to see if this issue is resolved in OC 2.0? I thought I'd read that 2.0 has user defined functions, and if it does it seems to me they would have had to solve this issue. Frank On 6/29/2013 4:29 AM, Sergey Kashyrin wrote:
|
[Prev in Thread] | Current Thread | [Next in Thread] |