1
       01  COUNTER.
           03  DIGITS1 OCCURS 40 TIMES PIC 9.
           03  STRING1 REDEFINES DIGITS1 pic X(40).

That compiles fine in Micro Focus Visual COBOL 2.3 in Visual Studio 2015. It gives an error in GnuCOBOL, viz

The original definition should not have OCCURS

Why the difference and what do I do to have an array of digits that can also be viewed as a string of digits?

Bill Woodger
  • 12,968
  • 4
  • 38
  • 47
bugmagnet
  • 7,631
  • 8
  • 69
  • 131

2 Answers2

4

It is either a COBOL Language Extension in Micro Focus Visual COBOL 2.3, or it is a bug there.

Indeed, locating some Micro Focus documentation reveals:

OSVS MF The data description for data-name-2 can contain an OCCURS clause.

OSVS and MF indicate what the Language Extension relates to. MF is Micro Focus, OSVS I assume is for OS/VS COBOL on an IBM Mainframe. I used that a lot, but since I don't code like that I can't say whether it worked like that. OS/VS COBOL was to the 1974 Standard.

Locating an old (1975) manual for OS/VS COBOL, here is the defintion of REDEFINES:

level number data-name-l REDEFINES data-name-2

That also serves for the Micro Focus quote.

Here is the relevant part from that OS/VS COBOL manual:

The data description entry far data-name-2 cannot contain an OCCURS clause

So I'm not so sure that OSVS in the Micro Focus document is OS/VS COBOL. I know the icons are listed somewhere...

From a draft of the 2015 Standard (it is expensive to obtain the actual Standard):

The data description entry for data-name-2 shall not contain an OCCURS clause. However, data-name-2 may be subordinate to an item whose data description entry contains an OCCURS clause. In this case, the reference to data-name-2 in the REDEFINES clause shall not be subscripted. Neither the original definition nor the redefinition shall include an occurs-depending table.

The 1985 Standard as it relates to the REDEFINES of an OCCURS is the same.

This should do for you:

   01  COUNTER.
       03  DIGITS1 OCCURS 40 TIMES PIC 9.

Just use COUNTER instead of STRING1 (I hope those names are just for this example, not the real ones).

COUNTER is a group item, which is treated as an alpha-numeric item with a total length equal to the sum of the lengths of all its subordinate items.

You want STRING1 to be a 40-byte PIC X field, when you already have one: COUNTER.

I always code my tables like this:

   01  FILLER.
       05  FILLER                            PIC something.
       05  FILLER.
           10  FILLER OCCURS 40 TIMES.
                15  FILLER                   PIC something.
       05  FILLER                            PIC something.

OK, conceptually I do that. Then, for each level of an OCCURS that I actually require, I give it a name. If there are items outside the OCCURS structure I don't need, I delete them.

With this, if you need to REDEFINES the group which contains the OCCURS, no problem. If you need to REDEFINES the OCCURing item, no problem. You can't REDEFINES (or do much useful) with the item actually containing the OCCURS, so it remains a FILLER.

This is for "maintainability". The next person along will never have to alter the structure of the OCCURS, so never have to worry when making a change. With the short-hand structure, a future change may require a reorganisation, which then has to be considered for impact.

If your table had been coded that way, there would not have been a problem anyway.

Consult your Micro Focus documentation for the REDEFINES, they usually indicate Language Extensions directly there. If there is not a Language Extension that you can locate, raise an issue with Micro Focus. They will point you to the documentation of the Extension, or do something else constructive with it.

Micro Focus the company has consumed some "small system" commercial compilers, and provides a lot of support to allow a migration path from those compilers to straight Micro Focus ones. My guess would be that you'll find a Language Extension linked to that.

Incidentally, it is also non-Standard to be able to REDEFINES a smaller item as a larger item. DIGITS1 has a length of one. Your REDEFINES item a length of 40. However, the Micro Focus REDEFINES is allowing you to redefine the entire length of the OCCURS.

Bill Woodger
  • 12,968
  • 4
  • 38
  • 47
2

By error, do you mean the warning?

   identification division.
   program-id. redef.

   data division.
   working-storage section.
   01  COUNTER.
       03  DIGITS1 OCCURS 40 TIMES PIC 9.
       03  STRING1 REDEFINES DIGITS1 pic X(40).

   procedure division.
   move 1 to DIGITS1(2)
   display ":" STRING1 ":"
   goback.
   end program redef.

with

prompt$ cobc -xj redef.cob
redef.cob: 8: Warning: The original definition 'DIGITS1' should not have  OCCURS
:0100000000000000000000000000000000000000:
prompt$ cobc --version
cobc (GNU Cobol) 2.0.0
Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Keisuke Nishida
Copyright (C) 2006-2012 Roger While
Copyright (C) 2009,2010,2012,2014,2015 Simon Sobisch
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Built     Nov 02 2015 05:58:19
Packaged  Oct 25 2015 21:40:28 UTC
C version "4.9.2 20150212 (Red Hat 4.9.2-6)"

So, that's GnuCOBOL 2.0.

prompt$ cobc -x redef.cob
redef.cob:8: Warning: The original definition 'DIGITS1' should not have OCCURS
prompt$ cobc --version
cobc (GNU Cobol) 1.1.0
 ...
prompt$ ./redef 
:0100000000000000000000000000000000000000:

Looks like it works with 1.1 as well.

I can't get rid of the warning though.

Brian Tiffin
  • 3,978
  • 1
  • 24
  • 34