tcfrey
asked on
Scratching my head.
Would someone kindly tell me why the following will not compile?
H Debug DftActGrp(*NO) Bnddir('QC2LE') ActGrp('New')
D GetProfile PR ExtPgm('QSYGETPH')
D UserID 10A const
D Password 10A const
D Handle 12A
D ErrorCode 32766A options(*varsize: *nopass)
/Free
GetProfile(UserID: PassWord: Handle: ErrorCode);
*InLR = *On;
/End-Free
The compiler messages are.
*RNF5410 30 1 The prototype for the call is not defined.
*RNF7030 30 4 The name or indicator is not defined.
*RNF7503 30 1 Expression contains an operand that is not defined.
I've been fighting this all day.
Thaks in advance
H Debug DftActGrp(*NO) Bnddir('QC2LE') ActGrp('New')
D GetProfile PR ExtPgm('QSYGETPH')
D UserID 10A const
D Password 10A const
D Handle 12A
D ErrorCode 32766A options(*varsize: *nopass)
/Free
GetProfile(UserID: PassWord: Handle: ErrorCode);
*InLR = *On;
/End-Free
The compiler messages are.
*RNF5410 30 1 The prototype for the call is not defined.
*RNF7030 30 4 The name or indicator is not defined.
*RNF7503 30 1 Expression contains an operand that is not defined.
I've been fighting this all day.
Thaks in advance
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Dave's right. (I haven't actually tried to compile the example, so there _could_ be detail differences; but just by looking, his explanation covers the compile errors.)
All that's happened for the four items that appear to be mentioned here --
RNF7030 30 4 The name or indicator is not defined.
-- is that the they've been given the same names as the items under the GetProfile prototype. But the items under GetProfile don't even need names; the fact that they're allowed names is maybe just an unfortunate judgment of the IBM compiler writers.
From the ILE RPG Reference: "For a prototype parameter definition, the name entry is optional. If a name is specified, the name is ignored."
The prototype, including its argument definitions, doesn't declare any memory. All it does is provide a template for the compiler. The compiler can use the prototype definitions to cross-check against the arguments you pass on the CALLP statement.
But the arguments on CALLP haven't been defined yet.
I know it seems confusing because the prototype sure makes it _look_ like they're defined.
To add to the confusion, when you create a PR/PI pair PR prototype and PI procedure interface) of specifications for the current program, you actually do define the arguments at that time -- kind of.
In this case, your prototype isn't for the current program; it's for an external program, the QSYGETPH API.
So why would a PR/PI pair for the current be allowed to define variables, but a PR for an external program (or procedure) not be allowed the same thing?
Well, generally you can think of it as being because when a parm value is accessed in the current program, the value is usually actually stored in the calling program's memory. You shouldn't need to declare space in the current program unless you need to make a copy of the value. The definitions in a PR/PI are nothing more than descriptions of memory that already is allocated. There is no need to declare any memory.
But when values are going to be passed to an external program, you need more than just definitions. You must create the variables themselves. The memory has to be somewhere when the called program tries to access it.
And as Dave shows, that requires a few additional specifications.
Tom
All that's happened for the four items that appear to be mentioned here --
RNF7030 30 4 The name or indicator is not defined.
-- is that the they've been given the same names as the items under the GetProfile prototype. But the items under GetProfile don't even need names; the fact that they're allowed names is maybe just an unfortunate judgment of the IBM compiler writers.
From the ILE RPG Reference: "For a prototype parameter definition, the name entry is optional. If a name is specified, the name is ignored."
The prototype, including its argument definitions, doesn't declare any memory. All it does is provide a template for the compiler. The compiler can use the prototype definitions to cross-check against the arguments you pass on the CALLP statement.
But the arguments on CALLP haven't been defined yet.
I know it seems confusing because the prototype sure makes it _look_ like they're defined.
To add to the confusion, when you create a PR/PI pair PR prototype and PI procedure interface) of specifications for the current program, you actually do define the arguments at that time -- kind of.
In this case, your prototype isn't for the current program; it's for an external program, the QSYGETPH API.
So why would a PR/PI pair for the current be allowed to define variables, but a PR for an external program (or procedure) not be allowed the same thing?
Well, generally you can think of it as being because when a parm value is accessed in the current program, the value is usually actually stored in the calling program's memory. You shouldn't need to declare space in the current program unless you need to make a copy of the value. The definitions in a PR/PI are nothing more than descriptions of memory that already is allocated. There is no need to declare any memory.
But when values are going to be passed to an external program, you need more than just definitions. You must create the variables themselves. The memory has to be somewhere when the called program tries to access it.
And as Dave shows, that requires a few additional specifications.
Tom
ASKER
Thanks to both of you.
Tom, thank you for the explination. It will take me a little while to absorb it but, I do understand better.
Thanks Again
Thomas
Tom, thank you for the explination. It will take me a little while to absorb it but, I do understand better.
Thanks Again
Thomas
Dave:
Not needed. Perhaps you've seen that I often add comments long after points have been awarded. I'm more interested in adding value to the AS/400 topic area as a whole.
In this case, most of what I added was purely personal interpretation of how I see procedure parm descriptions working. Maybe it helps illuminate for others; maybe it just makes it more confusing.
And maybe a discussion thread will expand and some real knowledge will get tacked on that will be useful to someone next year.
I'm just in it for the fun of it, I guess.
Tom
Not needed. Perhaps you've seen that I often add comments long after points have been awarded. I'm more interested in adding value to the AS/400 topic area as a whole.
In this case, most of what I added was purely personal interpretation of how I see procedure parm descriptions working. Maybe it helps illuminate for others; maybe it just makes it more confusing.
And maybe a discussion thread will expand and some real knowledge will get tacked on that will be useful to someone next year.
I'm just in it for the fun of it, I guess.
Tom
ASKER
I found out after the fact. Sorry
you have only defined the prototype. This does not define the variables.
Define
D UserID s 10A
D Password s 10A
D Handle s 12A
as stansd alone variables
and define error code as
D ErrorDS ds 16
D BytesProv 10i 0 inz(%size(ErrorDS))
D BytesAvail 10i 0
D ExceptionID 7
it is best to deing the prototype as
D GetProfile PR ExtPgm('QSYGETPH')
D UserID 10A const
D Password 10A const
D Handle 12A
D ErrorCode Like(ErrorDS)
have fun
Dave