gnucobol-users
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [open-cobol-list] procedure division returning


From: Michael Anderson
Subject: Re: [open-cobol-list] procedure division returning
Date: Fri, 28 Jun 2013 02:00:56 -0500
User-agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130623 Thunderbird/17.0.7

Sorry Frank, I assumed that you did not want to return because you had 'len' in the using clause of the procedure division of calllee2.

Note: That you had 'len' in the callee2 procedure division using list, but you did not pass it in the call statement, and therefore len does not have a memory address.
You could have given len a memory address first using the set statement, but instead you try to give 'len' a value, and vala: core-dump, SEGV..... NULL pointer.

So, the solution would be to pass len to callee2, then it will have a memory address, give it a value, and then move len to return-code before exit.

Here is another version: old_test.cob
Also NOTE: I did not include the source format line, and I removed all reference to 'function' by compiler directives:
cobc -x -free -ffunctions-all old_test.cob

program-id. caller.
data division.
local-storage section.
77  str-len  binary-long.
procedure division.
    call 'callee1' using  'This is a test'
         returning str-len
    display str-len
    Move 0 To str-len.
    call 'callee2' using  'This is a test!' str-len
         returning str-len
    display str-len
    goback.
end program caller.

program-id. callee1.
data division.
linkage section.
01  str  pic x any length.
procedure division using str.
    compute return-code = length(str)
    exit program.
end program callee1.

program-id. callee2.
data division.
linkage section.
01  str  pic x any length.
01  len  binary-long.
procedure division using str returning len.
    compute len = length(str) end-Compute
    move len to return-code
    exit program.
end program callee2.





On 06/28/2013 01:26 AM, Frank Swarbrick wrote:
That works, of course, because you're no longer using the returning phrase.

The problem is that I'm trying to use JNI to interface Java with COBOL.  And it works, except in Java you can only pass by value, which means the only way to get a result is to "return" it.  So it requires use of PROCEDURE DIVISION RETURNING if I want to pass anything from COBOL back to Java.

BTW, I think the reason your one test returned 14 instead of 15 is because it was using the return-code result from the call to callee1.

Frank

On 6/28/2013 12:13 AM, Michael Anderson wrote:
Can't explain, but try this:
Change to call to callee2 to:
call 'callee2' using content 'This is a test!' by reference str-len

And the procedure division of callee2, to:
procedure division using str len.

That should make it work, but still does not answer the question.
The Cobol default for passing data to sub routines is "By Reference",  so theoretically you don't need to add "by reference".
Sure enough, without the "by reference" it does not core dump, but the result is 14, when it should be 15. very odd indeed.

Adding the "by reference" makes it work as expected, icallee2 sets len to equal 15.

Also, the "content" clause is not needed, when passing a literal it is the default.
Passing len by reference is just passing the address, not a copy of the value, like in C &len, is the same as "by reference len" in Cobol.)

My version works: compiled using "cobc -x -free"

program-id. caller.
data division.
local-storage section.
77  str-len  binary-long.
procedure division.
    call 'callee1' using 'This is a test'
         returning str-len
    display str-len
    call 'callee2' using 'This is a test!' by reference str-len
    display str-len
    goback.
end program caller.

program-id. callee1.
data division.
linkage section.
01  str  pic x any length.
procedure division using str.
    compute return-code = function length(str)
    exit program.
end program callee1.

program-id. callee2.
data division.
linkage section.
01  str  pic x any length.
01  len  binary-long.
procedure division using str len.
    compute len = function length(str)
    exit program.
end program callee2.


On 06/28/2013 12:35 AM, Frank Swarbrick wrote:
Anyone ever got this to work?
Take a look at this:

       >>SOURCE FORMAT IS FREE

program-id. caller.
data division.
local-storage section.
77  str-len  binary-long.
procedure division.
    call 'callee1' using content 'This is a test'
         returning str-len
    display str-len
    call 'callee2' using content 'This is a test!'
         returning str-len
    display str-len
    goback.
end program caller.

program-id. callee1.
data division.
linkage section.
01  str  pic x any length.
procedure division using str.
    compute return-code = function length(str)
    exit program.
end program callee1.

program-id. callee2.
data division.
linkage section.
01  str  pic x any length.
01  len  binary-long.
procedure division using str returning len.
    compute len = function length(str)
    exit program.
end program callee2.

callee1 works fine.  callee2 causes a core dump or some such thing.

Looking at the generated C code I see the following:

/* PROGRAM-ID : callee1 */
static cob_u8_t b_8[4];    /* RETURN-CODE */

/* PROGRAM-ID : callee2 */
static cob_u8_t b_14[4];    /* RETURN-CODE */


/* PROGRAM-ID : callee1 */
static cob_field f_8    = {4, b_8, &a_3};    /* RETURN-CODE */
static cob_field f_12    = {1, NULL, &a_1};    /* str */

/* PROGRAM-ID : callee2 */
static cob_field f_18    = {1, NULL, &a_1};    /* str */
static cob_field f_19    = {4, NULL, &a_2};    /* len */

/* LINKAGE SECTION (Items not referenced by USING clause) */
static unsigned char    *b_19 = NULL;  /* len */


The compute in callee1:
    cob_decimal_set_field (&d0, cob_intr_length (&f_12));
    cob_decimal_get_field (&d0, &f_8, 0);

The compute in callee2:
    cob_decimal_set_field (&d0, cob_intr_length (&f_18));
    cob_decimal_get_field (&d0, (f_19.data = "" &f_19), 0);

So what's happening is that in callee2 variable 'b_19', which is the address of the COBOL field 'len' is still set to NULL, and thus we get a null pointer exception when trying to set it.

So it seems to me that even though the returning clause of the procedure division is allowed syntactically its not actually supported in the run-time.  Bad news!  :-(

Interestingly, a small kludge will make it work.  I added the following before any attempt to use the returning field (len):
    set address of len to address of return-code

And now it works.

Comments?


------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev


_______________________________________________
open-cobol-list mailing list
address@hidden
https://lists.sourceforge.net/lists/listinfo/open-cobol-list



------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev


_______________________________________________
open-cobol-list mailing list
address@hidden
https://lists.sourceforge.net/lists/listinfo/open-cobol-list



reply via email to

[Prev in Thread] Current Thread [Next in Thread]