ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

Why does this constant have to be gloablly defined?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Why does this constant have to be gloablly defined?

    I have a global /copy member "myMember" defining DS:
    Code:
    dcl-ds myDs     qualified template;
      myNum         packed(7);
    end-ds;
    I want to create varchars with the same length as that packed numeric. So I do this:
    Code:
    //global:
    /copy myMember;
    dcl-c fieldLen  const(%len(myDs.myNum));
    
    dcl-pr myProc;
      dcl-s myStr     varchar(fieldLen);
    ...
    end-pr;
    Define a constant as the length of the packed numeric, then define a varchar based on that constant.

    This works, as long as the constant is global.

    But if the constant is in the subprocedure instead:
    Code:
    //global:
    /copy myMember;
    
    dcl-pr myProc;
      dcl-c fieldLen  const(%len(myDs2.myNum));
      dcl-s myStr     varchar(fieldLen);
    ...
    end-pr;
    Then it fails to compile with error RNF3320 "The keyword parameter is not defined; keyword is ignored" on the constant definition line.

    But I don't see why this shouldn't work?


  • #2
    This may not solve your problem, but just ask the following questions:
    Why to define a constant locally?
    Does it make sense?

    Comment


    • #3
      It made sense because the constant was for a variable that was only local to the procedure, though there is no reason it couldn't be global.

      I was more curious if there was a reason why it had to be global that I was missing, or if it's a simple oversight in the compiler

      Comment


      • #4
        Originally posted by Vectorspace View Post
        ...

        I was more curious if there was a reason why it had to be global that I was missing, or if it's a simple oversight in the compiler
        Have you checked PTFs? I seem to recall a similar issue a way back. This may already have been fixed.

        Comment


        • #5
          RPG allows "forward referencing", which means that you can use a variable before you define it. Normally, when you use a name in a subprocedure and the name isn't defined yet in the subprocedure, RPG assumes that you might define it later in the subprocedure. If it turns out to be a global name, RPG doesn't figure that out until the end of the subprocedure. When you define your named constant as %LEN(myDs.myNum) in the subprocedure, RPG assumes that you might be defining myDs later in the subprocedure.

          But for parameters of definition keywords, like VARCHAR, if the definition is in a subprocedure, RPG will check to see whether there is a global named constant with that name. If so, it will use the global constant. (And if you define that name locally later in the procedure, you'll get an error saying that the global name was already used.)

          But this feature only applies to global named constants. When the definition of the named constant itself is in the subprocedure, and the named constant is a bulit-in function like %LEN(globalName), RPG doesn't have the ability to figure out whether "globalName" is a global field that it could use for the %LEN.

          A complicated way of saying that the behaviour is expected, even if it seems very capricious.

          Comment


          • Vectorspace
            Vectorspace commented
            Editing a comment
            Detailed and informative - thanks Barbara, much appreciated!
        Working...
        X