I think gyt3 has a problem with terminology. The name of a data set in a generation data set group has three parts:

- The name of the base of the generation data group, which we will say is BASE.
- The generation, which we will say is gggg. The value for gggg always starts with 0001.
- A version of the generation, which we will say is vv. The purpose of a "version" is to replace a defective previous version. The value for vv always starts at 00.

The true name of the data set is BASE.GggggVvv.

If there are no data sets in the generation data group, BASE(+1) will allocate BASE.G0001V00.

GDG data sets are normally named by their relative generation in JCL; if a GDG is used in JCL, the match between the relative generation and a true generation is fixed for the life of the job. So, if at the start of a job you have

BASE.G0101V00

BASE.G0102V01

BASE.G0103V00

BASE(0) is BASE.G0103V00

BASE(-1) is BASE.G0102V01

BASE(-2) is BASE.G0101V00

BASE(+1) is BASE.G0104V00 (for a new data set created in the job)

BASE(+2) is BASE.G0105V00 (for a new data set created in the job)

The use of relative generations should be avoided by services such as FTP and in TSO and by programs using dynamic allocation.

One defect in this scheme is it is not readily possible to detect obvious errors. For example, BASE(-3) does not exist, but it is not possible to bypass a step that wants to use BASE(-3). Similarly,

//A EXEC PGM=...

//NEW DD DISP=(NEW,CATLG),DSN=BASE(+1),...

//B EXEC PGM=...

//OLD DD DISP=OLD,DSN=BASE(-2)

will fail if the GDG base is defined to scratch data sets; step A will scratch G0101V00 when it creates G0104V00, so the data set is gone when step B tries to execute.