GCOBOL(1)
π gcobol β GCC COBOL Front-end π
okay bestie, welcome to GCOBOL(1) from the GCC COBOL Compiler manual β¨ grab ur boba, we're going in, and we are not skipping a single flag π
π NAME π
gcobol β GCC COBOL Front-end π
β¨ SYNOPSIS β¨
gcobol [-Dname[=value]] [-E] [-fdefaultbyte=value] [-fsyntax-only]
[-Icopybook-path] [-fmax-errors=nerror] [-nomain | -main filename
| -main=filename -main=filename:program-id]
[-fcobol-exceptions exception[,exception...]] [-copyext ext]
[-ffixed-form | -ffree-form] [-findicator-column]
[-fexec-charset=encoding] [-fexec-national-charset=encoding]
[-dialect dialect-name] [-include filename]
[-preprocess preprocess-filter] [-fflex-debug] [-fyacc-debug]
[-Wno-apply-commit] [-Wno-file-code-set] [-Wno-high-order-bit]
[-Wno-bad-line-directive] [-Wno-bad-numeric]
[-Wno-binary-long-long] [-Wno-call-giving] [-Wno-call-literal]
[-Wno-cdf-dollar] [-Wno-cdf-invalid-parameter]
[-Wno-cdf-name-not-found] [-Wno-cobol-eject] [-Wno-cobol-resume]
[-Wno-cobol-volatile] [-Wno-comp-6] [-Wno-comp-x]
[-Wno-copybook-found] [-Wno-ec-unknown] [-Wno-entry-convention]
[-Wno-iconv-error] [-Wno-include-file-found]
[-Wno-include-file-not-found] [-Wno-inspect-trailing]
[-Wno-length-of] [-Wno-level-1-occurs] [-Wno-level-78]
[-Wno-level-78-defined] [-Wno-literal-concat] [-Wno-locale-error]
[-Wno-move-corresponding] [-Wno-move-index] [-Wno-move-pointer]
[-Wno-nllanginfo-error] [-Wno-operator-space]
[-Wno-preprocessor-error] [-Wno-procedure-not-found]
[-Wno-procedure-pointer] [-Wno-replace-error]
[-Wno-returning-number] [-Wno-segment-error]
[-Wno-segment-negative] [-Wno-stop-number] [-Wno-stray-indicator]
[-Wno-usage-typename] [-Wno-recording-mode] [-Wno-set-locale-to]
[-Wno-set-to-locale] filename [...]
look at that wall of -Wno- flags, she's iconic and she's thorough π«Ά
π« DESCRIPTION π«
gcobol compiles COBOL source code to object code, and optionally produces an executable binary or shared object. As a GCC component, it accepts all the options that affect code-generation and linking. The COBOL-specific ones are listed below, and yes we are doing every single one, no cap π§
-main filenameβgcobolwill generate amain()function as an entry point calling the firstPROGRAM-IDin filename.
-main is the default. When none of -nomain, -c, or -shared is present, an implicit -main is inserted into the command line ahead of the first source file name β¨
-main=filenameβ the.oobject module for filename will include amain()entry point calling the firstPROGRAM-IDin filename π-main=filename:program-idβ the.oobject module for filename will include amain()entry point that calls the program-id entry point π-nomainβ nomain()entry point will be generated by this compilation. The-nomainoption is incompatible with-main, and is implied by-shared. It is also implied by-cwhen there is no-mainpresent.
See below for examples showing the use of -main and -nomain π
-D name[=expr]β define a CDF name (for use with>>IF) to have the value of expr.-Eβ write the CDF-processed COBOL input to standard output in free-form reference format. Certain non-COBOL markers are included in the output to indicate where copybook files were included. For line-number consistency with the input, blank lines are retained.
Unlike the C compiler, This option does not prevent compilation. To prevent compilation, use the option -fsyntax-only also. (yes, also, she's extra like that π)
-fdefaultbyte=valueβ use value, a number between 0 and 255, as the default value for allWORKING-STORAGEdata items that have noVALUEclause. By default, alphanumeric data items are initialized with blanks, and numeric data items are initialized to zero. This option overrides the default with value πΈ-fsyntax-onlyβ invoke only the parser. Check the code for syntax errors, but don't do anything beyond that. the vibe check, and nothing else π-copyext extβ for the CDF directive
COPY name
if name is unquoted, several varieties of name are tried, as described below under Copybooks. The -copyext option extends the names searched to include ext. If ext is all uppercase or all lowercase, both forms are tried, with preference given to the one supplied. If ext is mixed-case, only that version is tried. For example, with
-copyext .abc
given the CDF directive
COPY name
gcobol will add to possible names searched βname.abcβ and βname.ABCβ in that order π¦
-ffixed-formβ use strict fixed-form reference format in reading the COBOL input: 72-character lines, with a 6-character sequence area, and an indicator column. Data past column 72 are ignored. π-ffree-formβ force the COBOL input to be interpreted as free-form reference format. Line breaks are insignificant, except that β*β at the start of a line acts as a comment marker. Equivalent to-indicator-column 0β¨-findicator-columnβ describes the location of the Indicator Area in a COBOL file in Reference Format, where the first 6 columns β known as the βSequence Number Areaβ β are ignored, and the 7th column β the Indicator Area β may hold a character of significance to the compiler.
Although reference format, strictly speaking, ignores data after column 72, with this option gcobol accepts long COBOL lines, sometimes known as extended source format. Text past column 72 is treated as ordinary COBOL text. (Line continuation remains in effect, however, provided no text appears past column 72.)
There is no maximum line length. Regardless of source code format, the entire program could appear on one line. π
By default, gcobol auto-detects the source code format by examining the line that contains the text "program-id". When there are characters on past column 72 on that line, the file is assumed to be in extended source format, with the indicator area in column 7. Otherwise, columns 1-6 are examined. If those characters are all digits or blanks, the file is assumed to be in fixed-form reference format, also with the indicator in column 7. If not auto-detected as fixed-form reference format or extended source format, the file is assumed to be in free-form reference format. she literally guesses and she's usually right π
-fcobol-exceptions exception [,exception...]β by default, no exception condition is enabled (including fatal ones), and by the ISO standard exception conditions are enabled only via the CDFTURNdirective. This option enables one or more exception conditions by default, as thoughTURNhad appeared at the top of the first source code file. This option may also appear more than once on the command line.
The value of exception is a Level 1, 2, or 3 exception condition name, as described by ISO/IEC 1989:2023. βEC-ALLβ means enable all exceptions π«Ά
The -fno-cobol-exceptions form turns off exception, just as though
>>TURN exception CHECKING OFF
had appeared.
Not all exception conditions are implemented. Any that are not produce a warning message. bestie, read ur warnings π
-fmax-errors=nerrorβ nerror represents the number of error messages produced. Without this option,gcobolattempts to recover from a syntax error by resuming compilation at the next statement, continuing until end-of-file. With it,gcobolcounts the messages as they're produced, and stops when nerror is reached. π-fstatic-call,-fno-static-callβ with-fno-static-call,gcobolnever uses static linking for
CALL program
By default, or with -fstatic-call, if program is an alphanumeric literal, gcobol uses static linkage, meaning the compiler produces an external symbol program for the linker to resolve. (In the future, that will work with CONSTANT data items, too.) With static linkage, if program is not supplied by the source code module or another object file or library at build time, the linker will produce an βunresolved symbolβ error. With -fno-static-call, gcobol always uses dynamic linking.
This option affects the CALL statement for literals only. If program is a non-constant data item, it is always resolved using dynamic linking, with dlsym(3), because its value is determined at run time. β
-fexec-charset=encodingβ set the default execution character set for alphanumeric data items and literals in the absence ofCHARACTER CLASSIFICATIONinCONFIGURATION SECTION. encoding is an encoding name as defined byiconv(3). Unless otherwise specified, the runtime encoding for both alphanumeric andNATIONALis CP1252 as defined byiconv(3)π-fexec-national-charset=encodingβ set the default execution character set forNATIONALdata items and literals in the absence ofCHARACTER CLASSIFICATIONinCONFIGURATION SECTION. encoding is an encoding name as defined byiconv(3). To use an EBCDIC encoding for data items, one might use
-fexec-national-charset=CP1140
for example π
-dialect dialect-nameβ by default,gcobolaccepts COBOL syntax as defined by ISO/IEC 1989:2023, with some extensions for backward compatibility with COBOL-85. Additional syntax is supported with this option. The value of dialect-name may be
ok so ibm is the vibe check for IBM COBOL 6.4 syntax, and here's the whole shopping list bestie:
EJECTEQUALas assignment operatorLENGTH OFPROCEDURE POINTERSECTIONsegmentSTOP <number>VOLATILE- Per-program Registers
RETURN-CODE S9(4)
SORT-CONTROL X(160)
SORT-CORE-SIZE S9(8)
SORT-FILE-SIZE S9(8)
SORT-MESSAGE X(8)
SORT-MODE-SIZE S9(5)
SORT-RETURN S9(4)
TALLY 9(5)
WHEN-COMPILED X(16)
XML-CODE S9(9)
XML-EVENT X(30)
XML-INFORMATION S9(9)
XML-NAMESPACE X(0) to X(32,768)
XML-NNAMESPACE N(0) to N(16,384)
XML-NAMESPACE-PREFIX X(0) to X(4,096)
XML-NNAMESPACE-PREFIX N(0) to N(2,048)
XML-NTEXT N(0) to N(2,000,000)
XML-TEXT X(0) to X(2,147,483,646)
gnuβ this one's for GnuCOBOL syntax, which is generally compatible with MicroFocus. iykyk πmfβ and this one is the MicroFocus syntax moment:BINARY-LONG-LONGCALL ... GIVINGCDF $IFCOMPUTATIONAL-6COMPUTATIONALused withPICTURE XINSPECT ... TRAILINGOCCURSatLEVEL 01LEVEL 78constantsMOVE POINTERRETURNING <number>USAGE IS TYPENAME
-includefilename β bestie this just slurps filename in as if
COPY βfilenameβ
showed up as the literal first line of the primary source file. π
Ok but listen: if filename is not an absolute path, the directory that gets searched is the current working directory, not the directory holding the main source file. The name is used verbatim. No permutations applied, no directories searched. Periodt.
And if you stack multiple -include options? They get included in the order they appear on the command line. In order, bestie. π
-preprocesspreprocess-filter β okay so after all the CDF text-manipulation has been applied, and before the prepared COBOL gets sent off to thecobol1compiler, the input may get further altered by one or more filters. In the sacred tradition ofsed(1), each preprocess-filter reads from standard input and writes to standard output. Iconic behavior honestly.
To supply options to preprocess-filter, use a comma-separated string, similar to how linker options get supplied to -Wl. > Do NOT put any spaces after the commas, because the shell will treat it as an option separator. π
gcobol replaces each comma with a space when preprocess-filter is invoked. So for example:
-preprocess tee,output.cbl
invokes tee(1) with the output filename argument output.cbl, which causes a copy of the input to be written to the file. cute!
gcobol searches the current working directory and the PATH environment variable directories for an executable file whose name matches preprocess-filter. The first one found is used. If none is found, an error is reported and the compiler is not invoked. π
The -preprocess option may appear more than once on the command line, and each preprocess-filter is applied in turn, in order of appearance.
The preprocess-filter should return a zero exit status, indicating success. If it returns a nonzero exit status, an error is reported and the compiler is not invoked. no cap.
-fflex-debug,-fyacc-debugβ these two produce messages useful for compiler development, so if you're not out here developing the compiler, this is giving "not for you bestie" energy. The-fflex-debugoption prints the tokenized input stream. The-fyacc-debugoption shows the shift and reduce actions taken by the parser. π¦
β¨ Diagnostic Messages β¨
Many warning options can be used to convert error messages to warnings, or to suppress messages related to COBOL dialects. The user may mix and match, bestie β it's a whole build-your-own-adventure. A group of features may be enabled by indicating a dialect (or more than one dialect) and individual features may be enabled as a warning, or error, or suppressed. π
-Wno-apply-commitβ Warn ifAPPLY COMMITis used.-Wno-bad-line-directiveβ Warn if malformed β#lineβ directive is encountered.-Wno-binary-long-longβ Warn ifBINARY-LONG-LONGis used.-Wno-call_givingβ Warn ifCALL ... GIVINGis used.-Wno-call_literalβ Warn ifCALLis used is used with a literal parameter by reference.-Wno-cdf-dollarβ Warn if CDF$IFis used.-Wno-comp-6β Warn ifCOMPUTATIONAL-6is used.-Wno-comp-xβ Warn ifCOMPUTATIONALis used withPICTURE X.-Wno-file-code-setβ Warn ifFILE CODE SETis used.-Wno-inspect-trailingβ Warn ifINSPECT ... TRAILINGis used.-Wno-level-1-occursβ Warn ifLevel 01is used withOCCURS.-Wno-level-78-definedβ Warn if CDF definesLevel 78constant.-Wno-move-indexβ Warn ifMOVE INDEXis used.-Wno-move-pointerβ Warn ifMOVE POINTERis used.-Wno-returning-numberβ Warn ifRETURNING <number>is used.-Wno-usage-typenameβ Warn ifUSAGE IS TYPENAMEis used.-Wno-bad-numericβ Warn if numeric string is invalid.-Wno-cdf-invalid-parameterβ Warn if referenced CDFPARAMETERis not defined.-Wno-cdf-name-not-foundβ Warn if referenced CDF name is not defined.-Wno-cobol-ejectβ Warn if IBM-styleEJECTis used (instead of error).-Wno-cobol-resumeβ Warn if ISORESUMEis used with-dialect ibm(instead of error).-Wno-cobol-volatileβ Warn ifVOLATILEis used (instead of error if-dialect ibm).-Wno-copybook-foundβ Print message when copybook is processed.-Wno-ec-unknownβ Warn if unimplemented/unknown exception condition is referenced.-Wno-entry-conventionβ Print message whenENTRY CONVENTIONis specified.-Wno-high-order-bitβ Warn ifHIGH-ORDER-LEFT HIGH-ORDER-RIGHTis used.-Wno-include-file-foundβ Print message when include file is processed.-Wno-length-ofβ Warn ifLENGTH OFis used.-Wno-level-78β Warn ifLevel 78is used.-Wno-literal-concatβ Warn if concatenated literals use different encodings.-Wno-locale-errorβ Warn iflocale(3)fails.-Wno-move-correspondingβ Warn if COBOLMOVEhas no corresponding fields.-Wno-nllanginfo-errorβ Warn ifnlanglanginfo(3)fails.-Wno-recording-modeβ Warn ifRECORDING MODEis used.-Wno-segmentβ Warn ifSECTIONsegments are used.-Wno-set-locale-toβ Warn ifSET LOCALE ... TOis used.-Wno-set-to-localeβ Warn ifSET ... TO LOCALEis used. `. Warn if a line directive is malformed (instead of error).-Wno-iconv-errorβ Warn ificonv(3)cannot convert between encodings (instead of error).-Wno-include-file-not-foundβ Warn if include file is not found (instead of error).-Wno-operator-spaceβ Warn if relational operator not followed by space (instead of error).-Wno-preprocessor-errorβ Warn if a preprocessor fails (instead of error).-Wno-procedure-pointerβ Warn ifPROCEDURE POINTERis used.-Wno-procedure-not-foundβ Warn if a referenced procedure is not found (instead of error).-Wno-replace-errorβ Warn ifREPLACEcannot be processed (instead of error).-Wno-segment-errorβ Warn if aSEGMENTsection is invalid (instead of error).-Wno-segment-negativeβ Warn if aSEGMENTrange is negative (instead of error).-Wno-stop-numberβ Warn if IBM-styleSTOP <number>is used (instead of error).-Wno-stray-indicatorβ Warn if indicator column has no recognized meaning (instead of error).
π COMPILATION SCENARIOS π
Okay bestie, this is the part where it all clicks. Let's go scenario by scenario. π
gcobol xyz.cob
gcobol -main xyz.cob
gcobol -main=xyz.cob xyz.cob
These are equivalent. The xyz.cob code is compiled and a main() function is inserted that calls the first PROGRAM-ID in the xyz.cob source file. slay.
gcobol -nomain xyz.cob elsewhere.o
The -nomain option prevents a main() function from being generated by the gcobol compiler. A main() entry point must be present in the elsewhere.o module; without it the linker will report a βmissing mainβ error. π
gcobol aaa.cob bbb.cob ccc.cob
gcobol -main aaa.cob bbb.cob ccc.cob
The two commands are equivalent. The three source code modules are compiled and linked together along with a generated main() function that calls the first PROGRAM-ID in the aaa.cob module.
gcobol aaa.cob bbb.cob -main ccc.cob
gcobol -main=ccc.cob aaa.cob bbb.cob ccc.cob
These two commands have the same result: An a.out executable is created that starts executing at the first PROGRAM-ID in ccc.cob. π
gcobol -main=bbb.cob:b-entry aaa.cob bbb.cob ccc.cob
An a.out executable is created that starts executing at the PROGRAM-ID b-entry. iconic.
gcobol -c aaa.cob
gcobol -c -main bbb.cob
gcobol -c ccc.cob
gcobol aaa.o bbb.o ccc.o
The first three commands each create a .o file. The bbb.o file will contain a main() entry point that calls the first PROGRAM-ID in bbb. The fourth links the three .o files into an a.out. and that's the whole pipeline bestie π«Ά
π¦ EBCDIC π¦
Ok so if you're working with mainframe COBOL programs that are meant for EBCDIC-encoded files, the -fexec-charset=cp1140 option is literally the moment. Here's the tea: with this option on, your COBOL text stays in ASCII, but your character literals and field initial values produce EBCDIC strings in the compiled binary, and any character data read from a file gets interpreted as EBCDIC data. Periodt.
And the file data does not get converted β nope, the file is just assumed to use EBCDIC representation. The string literals in the COBOL text do get converted though, so they can be compared meaningfully with the data in the file. Iconic behaviour tbh.
Code Page 1140 is one of a number of EBCDIC code pages. It's often useful because it closely parallels the commonly-used Code Page 1252, which provides many Western European characters. π
Only file data and character literals are affected, bestie. Data read from and written to the environment, or taken from the command line, are interpreted according to the locale(7) in force during execution. The same is true of ACCEPT and DISPLAY. Names known to the operating system β such as file names and the names of environment variables β are processed verbatim. No cap.
At the present time, this is an all-or-nothing setting. Support forUSAGEandCODESET, which would allow conversion between encodings, remains a future goal. π
See also βFeature-set Variablesβ, below.
πΈ REDEFINES ... USAGE POINTER πΈ
So per ISO, an item that REDEFINES another may not be larger than the item it redefines β unless that item has LEVEL 01 and is not EXTERNAL. Them's the rules.
But in gcobol, when you use -dialect ibm, this rule gets relaxed for REDEFINES with USAGE POINTER whose redefined member is a 4-byte USAGE COMP-5 (usually PIC S9(8)), or vice-versa. In that case, the redefined member is re-sized to 8 bytes, to accommodate the pointer. The way that just works? Obsessed.
This feature allows pointer arithmetic on a 64-bit system with source code targeted at a 32-bit system. Main character energy fr fr.
See also βFeature-set Variablesβ, below.
π IMPLEMENTATION NOTES π
gcobol is a gcc compiler, and follows gcc conventions where applicable. Sometimes those conventions (and user expectations) conflict with common Mainframe practice. Unless required of the compiler by the ISO specification, any such conflicts are resolved in favor of gcc. Periodt.
π Linking π
Unlike C, the COBOL CALL statement implies dynamic linking, because for
CALL program
program can be a variable whose value is determined at runtime. Sneaky, right?
However, the parameter may also be a compile-time constant β either an alphanumeric literal, or a CONSTANT data item. β¨
gcobol supports static linking where possible, unless defeated by -fno-static-call. If the parameter value is known at compile time, the compiler produces an external reference to be resolved by the linker. The referenced program is normally supplied via an object module, a static library, or a shared object. If it is not supplied, the linker will report an βunresolved symbolβ error β either at build time or, if using a shared object, when the program is executed. This feature informs the programmer of the error at the earliest opportunity. Considerate king behaviour. π«Ά
Programs that are expected to execute correctly in the presence of an unresolved symbol (perhaps because the program logic won't require that particular CALL) can use the -no-static-call option. That forces all CALL statements to be resolved dynamically, at runtime.
π Implemented Exception Conditions π
By default, per ISO, no EC is enabled. Implemented ECs may be enabled on the command line or via the TURN directive. Any attempt to enable an EC that is not implemented is treated as an error.
An enabled EC not handled by a DECLARATIVE is written to the system log and to standard error. (The authors intend to make that an option.) A fatal EC not handled with RESUME ends with a call to abort(3) and process termination. Yeah. It's giving final boss.
Not all Exception Conditions are implemented. Any attempt to enable an EC that is not implemented produces a warning message. The following are implemented:
EC-FUNCTION-ARGUMENTβ for the following functions:ACOS,ANNUITY,ASIN,LOG,LOG10,PRESENT-VALUE,SQRTEC-SORT-MERGE-FILE-OPENEC-BOUND-SUBSCRIPTβ subscript not an integer, less than 1, or greater than occursEC-BOUND-REF-MODβ refmod start not an integer, start less than 1, start greater than variable size, length not an integer, length less than 1, and start+length exceeds variable sizeEC-BOUND-ODOβDEPENDINGnot an integer, greater than occurs upper limit, less than occurs lower limit, and subscript greater thanDEPENDINGfor sending itemEC-SIZE-ZERO-DIVIDEβ for both fixed-point and floating-point divisionEC-SIZE-TRUNCATIONEC-SIZE-EXPONENTIATION
As of this writing, no COBOL compiler documents a complete implementation of ISO/IEC 1989:2023 Exception Conditions. gcobol will give priority to those ECs that the user community deems most valuable. π¦
π EXTENSIONS TO ISO COBOL π
Standard COBOL has no provision for environment variables as defined by Unix and Windows, or command-line arguments. gcobol supports them using syntax similar to that of GnuCOBOL. ISO and IBM also define incompatible ways to return the program's exit status to the operating system. gcobol supports IBM syntax.
π Environment Variables π
To read an environment variable:
ACCEPT target FROM ENVIRONMENT envar
where target is a data item defined in DATA DIVISION, and envar names an environment variable. envar may be a string literal or alphanumeric data item whose value is the name of an environment variable. The value of the named environment variable is moved to target. The rules are the same as for MOVE. Slay.
To write an environment variable:
SET ENVIRONMENT envar TO source
where source is a data item defined in DATA DIVISION, and envar names an environment variable. envar again may be a string literal or alphanumeric data item whose value is the name of an environment variable. The value of the named environment variable is set to the value of source. π
π Command-line Arguments π
To read command-line arguments, use the registers COMMAND-LINE and COMMAND-LINE-COUNT in an ACCEPT statement (only). Used without a subscript, COMMAND-LINE returns the whole command line as a single string. With a subscript, COMMAND-LINE is a table of command-line arguments. For example, if the program is invoked as
./program -i input output
then
ACCEPT target FROM COMMAND-LINE(3)
moves input into target. The program name is the first thing in the whole command line and is found in COMMAND-LINE(1) COMMAND-LINE table.
To discover how many arguments were provided on the command line, use
ACCEPT target FROM COMMAND-LINE-COUNT
If ACCEPT refers to a nonexistent environment variable or command-line argument, the target is set to LOW-VALUES. π
The system command line parameters can also be accessed through the LINKAGE SECTION in the program where execution starts. The data structure looks like this:
linkage section.
01 argc pic 999.
01 argv.
02 argv-table occurs 1 to 100 times depending on argc.
03 argv-element pointer.
01 argv-string pic x(100) .
and the code to access the third parameter looks like this
procedure division using by value argc by reference argv.
set address of argv-string to argv-element(3)
display argv-string
β #line directive β
The parser accepts lines in the form
#line lineno βfilenameβ.
The effect is to set the current line number to lineno and the current input filename to filename. Preprocessors may use this directive to control the filename and line numbers reported in error messages and in the debugger. Very demure, very mindful.
π§ SELECT ... ASSIGN TO π§
In the phrase
ASSIGN TO filename
filename may appear in quotes or not. If quoted, it represents a filename as known to the operating system. If unquoted, it names either a data element or an environment variable containing the name of a file. If filename matches the name of a data element, that element is used. If not, resolution of filename is deferred until runtime, when the name must appear in the program's environment. β¨
π XML PARSE π
gcobol emulates the IBM XML PARSE statement. The following values for XML-EVENT are defined:
COMMENTβ text of a comment between"<!--"and"-->".CONTENT-CHARACTERSβ some or all of the character content of the element between start and end tags.END-OF-ELEMENTβ end-element tag, with name if present in the input.PROCESSING-INSTRUCTION-DATAβ processing instruction (after the target name), excluding"?>".PROCESSING-INSTRUCTION-TARGETβ the processing instruction target name appears inXML-TEXTorXML-NTEXT.START-OF-ELEMENTβ name of the start element tag or empty element tag.
ISO COBOL Implementation Status π«
USAGE Data Types
okay bestie, here's the tea on USAGE IS β gcobol serves up these:
INDEXβ for use as an index in a table. π―POINTERβ for variables whose value is the address of an external function, aPROGRAM-ID, or a data item. You assign to it via theSETstatement.BINARY,COMP,COMPUTATIONAL,COMP-4,COMPUTATIONAL-4β big-endian integer, 1 to 16 bytes, sized perPICTURE.COMP-1,COMPUTATIONAL-1,FLOAT-BINARY-32β IEEE 754 single-precision (4-byte) floating point, as provided by the hardware. π₯οΈCOMP-2,COMPUTATIONAL-2,FLOAT-BINARY-64β IEEE 754 double-precision (8-byte) floating point, as provided by the hardware.COMP-3,COMPUTATIONAL-3,PACKED-DECIMALβ currently unimplemented. π not yet, babes.COMP-5,COMPUTATIONAL-5β little-endian integer, 1 to 16 bytes, perPICTURE.FLOAT-BINARY-128,FLOAT-EXTENDEDβ 128-bit floating point, per IEEE 754. β¨
gcobol supports the ISO integer BINARY-<type> types, and most of them alias COMP-5. Here's the compatibility chart, every last cell, untouched:
COMP-5 Compatible
Picture BINARY Type Bytes Value
BINARY-CHAR 1 0 β 256
[UNSIGNED]
S9(1...4) BINARY-CHAR 1 -128 β +127
SIGNED
9(1...4) BINARY-SHORT 2 0 β 65535
[UNSIGNED]
S9(1...4) BINARY-SHORT 2 -32768 β +32767
SIGNED
9(5...9) BINARY-LONG 4 0 β 4,294,967,295
[UNSIGNED]
S9(5...9) BINARY-LONG 4 -2,147,483,648 β
SIGNED +2,147,483,647
9(10...18) BINARY-LONG-LONG 8 0 β
[UNSIGNED] 18,446,744,073,709,551,615
S9(10...18) BINARY-LONG-LONG 8 -9,223,372,036,854,775,808
SIGNED β
+9,223,372,036,854,775,807
These define a size (in bytes) and cannot be used with a PICTURE clause. And per the ISO standard, SIGNED is the default for the BINARY-type aliases. π
All computation β integer and floating point alike β is done using 128-bit intermediate forms. no cap. π
Environment Names
In gcobol,
DISPLAY UPON
maps SYSOUT and STDOUT to standard output, and SYSPUNCH, SYSPCH and STDERR to standard error. π«Ά
Exit Status
gcobol supports the ISO syntax for returning an exit status to the operating system:
STOP RUN [WITH] {NORMAL | ERROR} [STATUS] status
And bonus round β gcobol also supports the IBM syntax for returning an exit status to the operating system. Just use the RETURN-CODE register:
MOVE ZERO TO RETURN-CODE.
GOBACK.
The RETURN-CODE register is defined as a 4-byte binary integer. β
π COMPILER-DIRECTING FACILITY π
β οΈ Use the CDF with caution β no comprehensive test suite has been identified. fr fr, tread carefully.
CDF Text Manipulation
COPY copybook [OF|BY library] [REPLACING ...]β If copybook is a literal, it's treated as a literal filename, which either does or does not exist. If copybook is a COBOL word, gcobol looks first for an environment variable named copybook and, if it finds one, uses the contents of that variable as the name of the copybook file. If that file doesn't exist, it keeps looking for a file named one of:copybook(literally)copybook.cpycopybook.CPYcopybook.cblcopybook.CBLcopybook.cobcopybook.COB
in that order. It looks first in the same directory as the source code file, and then in any copybook-path named with the -I option. copybook-path may (like the shell's PATH variable) be a colon-separated list. The -I option may occur multiple times on the command line. Each successive copybook-path is concatenated to previous ones. Relative paths (having no leading β/β) are searched relative to the compiler's current working directory.
For example,
-I /usr/local/include:include
searches first the directory where the COBOL program is found, next in /usr/local/include, and finally in an include subdirectory of the directory from which gcobol was invoked. π¦
For the REPLACING phrase, both the modern pseudo-text and the COBOL/85 forms are recognized. (The older forms are used in the NIST CCVS/85 test suite.)
REPLACE ...β gcobol supports the full ISOREPLACEsyntax. slay. π
CDF Directives
>>DEFINE name AS {expression | PARAMETER} [OVERRIDE]β Define name as a compilation variable to have the value expression. If name was previously defined,OVERRIDEis required, else the directive is invalid.AS PARAMETERis accepted, but has no effect in gcobol.>>DEFINE name AS OFFβ releases the definition name, making it subsequently invalid for use.>>IF cce text [>>ELSE alt-text] >>END-IFβ evaluates cce, a constant conditional expression, for conditional compilation. If cce is a name, it may be defined with the-Dcommand-line parameter. If true, the COBOL text text is compiled. If false, else-text, if present, is compiled.[IS [NOT]] DEFINEDis supported. Boolean literals are not supported.>>EVALUATEβ Not implemented. π>>CALL-CONVENTION conventionβ convention may be one of:COBOLβ Use standard COBOL case-insensitive symbol-name matching. ForCALL "name", name is rendered by the compiler in lowercase.Cβ Use case-sensitive symbol-name matching. TheCALLtarget is not changed in any way; it is used verbatim.VERBATIMβ An alias for>>CALL-CONVENTION C.
>>COBOL-WORDS EQUATE keyword WITH aliasβ makes alias a synonym for keyword.>>COBOL-WORDS UNDEFINE keywordβ keyword is removed from the COBOL grammar. Use of it in a program will provoke a syntax error from the compiler. π>>COBOL-WORDS SUBSTITUTE keyword BY new-wordβ keyword is deleted as a keyword from the grammar, replaced by new-word. keyword may thereafter be used as a user-defined word.>>COBOL-WORDS RESERVE new-wordβ Treat new-word as a COBOL keyword. It cannot be used by the program, either as a keyword or as a user-defined word.>>DISPLAY string ...β Write string to standard error as a warning message.>>SOURCE formatβ format may be one of:FIXEDβ Source conforms to COBOL fixed-form reference format with unlimited line length.FREEβ Source conforms to COBOL free-form reference format. β*β at the beginning of a line is recognized as a comment.
>>FLAG-02β Not implemented.>>FLAG-85β Not implemented.>>FLAG-NATIVE-ARITHMETICβ Not implemented.>>LEAP-SECONDβ Not implemented.>>LISTINGβ Not implemented.>>PAGEβ Not implemented.>>PROPAGATEβ Not implemented.>>PUSH directive>>POP directiveβ WithPUSH, push CDF state onto a stack. WithPOP, return to the prior pushed state. directive may be one ofCALL-CONVENTION,COBOL-WORDS,DEFINE,SOURCE FORMAT,TURN.>>TURN [ec [file ...] ...] CHECKING {[ON] [[WITH] LOCATION] | OFF}β Enable (or, withOFF, disable) exception condition ec, optionally associated with the file connectors file. IfLOCATIONis specified, gcobol reports at runtime the source filename and line number of the statement that triggered the exception condition. π
Feature-set Variables
Some command-line options affect CDF feature-set variables that are special to gcobol. You can set and test them using >>DEFINE and >>IF, and they stand out by a leading β%β in the name β which is otherwise invalid in a COBOL identifier:
%EBCDIC-MODEβ is set by-fexec-charset=<encoding>for all EBCDIC encodings.%64-BIT-POINTERβ is implied by-dialect ibm.
To set a feature-set variable, use
>>SET feature [AS] {ON | OFF}
If feature is %EBCDIC-MODE, the directive must appear before PROGRAM-ID.
To test a feature-set variable, use
>>IF feature DEFINED
Intrinsic functions
gcobol implements all intrinsic functions defined by ISO/IEC 1989:2023, plus a few others. Listed alphabetically below, exactly as promised: πΈ
ABS ACOS ANNUITY ASIN ATAN
BASECONVERT BIT-OF BIT-TO-CHAR BOOLEAN-OF-INTEGER BYTE-LENGTH
CHAR CHAR-NATIONAL COMBINED-DATETIME CONCAT CONVERT COS CURRENT-DATE
DATE-OF-INTEGER DATE-TO-YYYYMMDD DAY-OF-INTEGER DAY-TO-YYYYDDD
DISPLAY-OF
E EXCEPTION-FILE EXCEPTION-FILE-N EXCEPTION-LOCATION
EXCEPTION-LOCATION-N EXCEPTION-STATEMENT EXCEPTION-STATUS EXP EXP10
FACTORIAL FIND-STRING FORMATTED-CURRENT-DATE FORMATTED-DATE
FORMATTED-DATETIME FORMATTED-TIME FRACTION-PART
HEX-OF HEX-TO-CHAR HIGHEST-ALGEBRAIC
INTEGER INTEGER-OF-BOOLEAN INTEGER-OF-DATE INTEGER-OF-DAY
INTEGER-OF-FORMATTED-DATE INTEGER-PART
LENGTH LOCALE-COMPARE LOCALE-DATE LOCALE-TIME LOCALE-TIME-FROM-SECONDS
LOG LOG10 LOWER-CASE LOWEST-ALGEBRAIC
MAX MEAN MEDIAN MIDRANGE MIN MOD MODULE-NAME
NATIONAL-OF NUMVAL NUMVAL-C NUMVAL-F ORD
ORD-MAX ORD-MIN
PI PRESENT-VALUE
RANDOM RANGE REM REVERSE
SECONDS-FROM-FORMATTED-TIME SECONDS-PAST-MIDNIGHT SIGN SIN
SMALLEST-ALGEBRAIC SQRT STANDARD-COMPARE STANDARD-DEVIATION SUBSTITUTE
SUM
TAN TEST-DATE-YYYYMMDD TEST-DAY-YYYYDDD TEST-FORMATTED-DATETIME
TEST-NUMVAL TEST-NUMVAL-C TEST-NUMVAL-F TRIM
ULENGTH UPOS UPPER-CASE USUBSTR USUPPLEMENTARY UUID4 UVALID UWIDTH
VARIANCE
WHEN-COMPILED
YEAR-TO-YYYY
Binary floating point DISPLAY
How the DISPLAY presents binary floating point numbers depends on the value. π
- When a value has six or fewer decimal digits to the left of the decimal point, it is expressed as
123456.789.... - When a value is less than 1 and has no more than three zeroes to the right of the decimal point, it is expressed as
0.0001234.... - Otherwise, exponential notation is used:
1.23456E+7.
In all cases, trailing zeroes on the right of the number are removed from the displayed value. β¨
COMP-1β shows up with 9 decimal digits πCOMP-2β shows up with 17 decimal digits β¨FLOAT-EXTENDEDβ shows up with 36 decimal digits π¦
Those digit counts are literally just matching what IEEE 754 asks for when you're interchanging info, no cap. Like, take COMP-2 binary64 values for example (per Wikipedia, bestie):
If an IEEE 754 double-precision number is converted to a decimal string with at least 17 significant digits, and then converted back to double-precision representation, the final result must match the original number.
17 digits got picked so that the DISPLAY statement can show you what's inside a COMP-2 variable without hiding a single crumb of information. π
π«Ά Binary floating point MOVE
Okay so during a MOVE statement, a floating-point value might get truncated. And ngl, it's genuinely not unusual for Numeric Display values to get altered when they get moved through a floating-point value. It's giving β¨chaosβ¨.
This program:
01 PICV999 PIC 9999V999.
01 COMP2 COMP-2.
PROCEDURE DIVISION.
MOVE 1.001 to PICV999
MOVE PICV999 TO COMP2
DISPLAY "The result of MOVE " PICV999 " TO COMP2 is " COMP2
MOVE COMP2 to PICV999
DISPLAY "The result of MOVE COMP2 TO PICV999 is " PICV999
generates this result:
The result of MOVE 0001.001 TO COMP2 is 1.00099999999999989
The result of MOVE COMP2 TO PICV999 is 0001.000
However, the internal implementation can produce results that might be seem surprising:
The result of MOVE 0055.110 TO COMP2 is 55.1099999999999994
The result of MOVE COMP2 TO PICV999 is 0055.110
The source of this inconsistency is the way gcobol stores and converts numbers. Converting the floating-point value to the numeric display value 0055110 is done by multiplying 55.109999... by 1,000 and then truncating the result to an integer. And it turns out that even though 55.11 can't be represented in floating-point as an exact value, the product of the multiplication, 55110, is an exact value. slay π
In cases where it is important for conversions to have predictable results, we need to be able to apply rounding, which can be done with an arithmetic statement:
MOVE 1.001 to PICV999
MOVE PICV999 TO COMP2
DISPLAY "The result of MOVE " PICV999 " TO COMP2 is " COMP2
MOVE COMP2 to PICV999
DISPLAY "The result of MOVE COMP2 TO PICV999 is " PICV999
ADD COMP2 to ZERO GIVING PICV999 ROUNDED
DISPLAY "The result of ADD COMP2 to ZERO GIVING PICV999 ROUNDED is " PICV999
The result of MOVE 0001.001 TO COMP2 is 1.00099999999999989
The result of MOVE COMP2 TO PICV999 is 0001.000
The result of ADD COMP2 to ZERO GIVING PICV999 ROUNDED is 0001.001
π Binary floating point computation
gcobol attempts to do internal computations using binary integers when possible. So like, simple arithmetic between binary values and numeric display values conclude with binary intermediate results. cute, right? π
But the moment a floating-point value gets included in the mix of variables specified for a calculation, then the intermediate result becomes a 128-bit floating-point value. she's different now π
π A warning about binary floating point comparison
The cardinal rule when doing comparisons involving floating-point values: Never, ever, test for equality. It's just not worth the hassle. fr fr, don't do it.
For example:
WORKING-STORAGE SECTION.
01 COMP1 COMP-1 VALUE 555.11.
01 COMP2 COMP-2 VALUE 555.11.
PROCEDURE DIVISION.
DISPLAY "COMPARE " COMP1 " with " COMP2
IF COMP1 EQUAL COMP2 DISPLAY "Equal" ELSE DISPLAY "Not equal" END-IF
MOVE COMP1 to COMP2
DISPLAY "COMPARE " COMP1 " with " COMP2
IF COMP1 EQUAL COMP2 DISPLAY "Equal" ELSE DISPLAY "Not equal" END-IF
the results:
COMPARE 555.1099854 with 555.110000000000014
Not equal
COMPARE 555.1099854 with 555.1099853515625
Equal
Why? Again, it has to do with the internals of gcobol. When differently sized floating-point values need to be compared, they are first converted to 128-bit floats. And it turns out that when a COMP1 is moved to a COMP2, and they are both converted to FLOAT-EXTENDED, the two resulting values are (probably) equal. π
Avoid testing for equality unless you really know what you are doing and you really test the code. And then avoid it anyway. periodt. π
Finally, it is observably the case that the gcobol implementations of floating-point conversions and comparisons don't precisely match the behavior of other COBOL compilers.
You have been warned. β οΈ π
πΈ ENVIRONMENT πΈ
COBPATHβ If defined, specifies the directory paths to be used by the gcobol runtime library,libgcobol.so, to locate shared objects. LikeLD_LIBRARY_PATH, it may contain several directory names separated by a colon (β:β).COBPATHis searched first, followed byLD_LIBRARY_PATH. Note thatCOBPATHdoes not change where the runtime linker looks forlibgcobol.soitself. How the runtime linker searches forlibgcobol.sowhen the executable loads is controlled byld.so(8), notlibgcobol. π
Each directory is searched for files whose name ends in β.soβ. For each such file, dlopen(3) is attempted, and, if successful dlsym(3). No relationship is defined between the symbol's name and the filename. π€
Without COBPATH, binaries produced by gcobol behave as one might expect of any program compiled with gcc. Any shared objects needed by the program are mentioned on the command line with a -llibrary option, and are found by following the executable's RPATH or otherwise per the configuration of the runtime linker, ld.so(8).
UPSIβ COBOL defines a User Programmable Status Indicator (UPSI) switch. In gcobol, the settings are denotedUPSI-0throughUPSI-7, where0-7indicates a bit position. The value of the UPSI switches is taken from theUPSIenvironment variable, whose value is a string of up to eight1's and0's. The first character represents the value ofUPSI-0, and missing values are assigned0. For example,UPSI=1000011in the environment sets bits 0, 5, and 6 on, which means thatUPSI-0,UPSI-5, andUPSI-6are on. π₯GCOBOL_TEMPDIRβ causes any temporary files created during CDF processing to be written to a file whose name is specified in the value ofGCOBOL_TEMPDIR. If the value is just β/β, the effect is different: each copybook read is reported on standard error. This feature is meant to help diagnose mysterious copybook errors. π΅οΈββοΈ
π§ Variables for Developers
GCOBOL_SHOWβ produces a trace of the internal calls made by the parser to prepare the GENERIC tree.GCOBOL_TRACEβ used at compile time, produces an executable that traces the execution, mapping it back the same code-creation functions asGCOBOL_SHOW, as well as the values of data items and branch conditions.
β FILES β
Executables produced by gcobol require the runtime support library libgcobol, which is provided both as a static library and as a shared object. two for the price of one, we love to see it π«Ά
π COMPATIBILITY π
The ISO standard leaves the default file organization up to the implementation; in gcobol, the default is SEQUENTIAL. (so that's the vibe check result, bestie)
πΈ On-Disk Format πΈ
Any ability to use files produced by other COBOL compilers, or for those compilers to use files produced by gcobol, is the product of luck and intuition. Various compilers interpret the ISO standard differently, and the standard's text is not always definitive. iykyk π
For ORGANIZATION IS LINE SEQUENTIAL files (explicitly or by default), gcobol, absent specific direction, produces an ordinary Linux text file: for each WRITE, the data are written, followed by an ASCII NL (hex 0A) character. On READ, the record is read up to the size of the specified record or NL, whichever comes first. The NL is not included in the data brought into the record buffer; it serves only as an on-disk record-termination marker. Consequently, SEQUENTIAL and LINE SEQUENTIAL files work the same way: the COBOL program never sees the record terminator. β¨
When READ and WRITE are used with ADVANCING, however, the game changes. If ADVANCING is used with LINE SEQUENTIAL files, it is honored by gcobol. π
Other compilers may not do likewise. According to ISO, in WRITE (14.9.47.3 General rules) ADVANCING is ignored for files for which βthe physical file does not support vertical positioningβ. It further states that, in the absence of ADVANCING, WRITE proceeds as if βas if the user has specified AFTER ADVANCING 1 LINEβ. Some other implementations interpret that to mean that the first WRITE to a LINE SEQUENTIAL file results in a leading NL on the first line, and no trailing NL on the last line. Some furthermore prohibit the use of ADVANCING with LINE SEQUENTIAL files. π
π STANDARDS π
The reference standard for gcobol is ISO/IEC 1989:2023, bestie. That's the whole vibe check. Here's how to read the situation:
- If
gcobolcompiles code that's consistent with that standard, the resulting program should execute correctly β anything else is a bug, periodt. - If
gcobolcompiles code that does not comply with that standard, but it runs correctly per some other specification? That's a non-standard extension. One day, the-pedanticoption will produce diagnostic messages for such code. (Not today. One day. π°οΈ) - If
gcobolrejects code that is consistent with that standard, that's an aspect of COBOL that is (or is not) on the To Do list. If you want to see it compile, please get in touch with the developers. They're nice. π«Ά
πΈ Status of NIST COBOL Compiler Verification Suite πΈ
Okay so here's the scoreboard, and it's giving overachiever:
NCβ 100% β NucleusSQβ 100% β Sequential I/ORLβ 100% β Relative I/OIXβ 100% β Indexed I/OICβ 100% β Inter-Program CommunicationSTβ 100% β Sort-MergeSMβ 100% β Source Text Manipulation RW \n Report WriterCMβ CommunicationDBβ to do? β DebugSGβ SegmentationIFβ 100% β Intrinsic Function
Where gcobol passes 100% of the tests in a module, we exclude the (few) tests for obsolete features. The authors regard features that were obsolete in 1985 to be well and truly obsolete today, and did not implement them. π like, respectfully, it's been decades.
π¦ Notable deferred features π¦
CCVS-85 modules not marked with any status above (CM, and SG) are on the "hard maybe" list β meaning they await an interested party with real code using the feature. So if that's you? Come through. β¨
gcobol does not implement Report Writer or Screen Section. Not a vibe, just a fact. π
π Beyond COBOL/85 π
gcobol increasingly implements ISO/IEC 1989:2023. For example, DECLARATIVES is not tested by CCVS-85, but is implemented by gcobol. Similarly, Exception Conditions were not defined in 1985, and gcobol contains a growing number of them. Growth mindset fr fr. π±
The authors are well aware that a complete, pure COBOL-85 compiler won't compile most existing COBOL code. Every vendor offered (and offers) extensions, and most environments rely on a variety of preprocessors and ancillary systems defined outside the standard. The express goal of adding an ISO COBOL front-end to GCC is to establish a foundation on which any needed extensions can be built. That's the whole point, bestie. That's the assignment. π
β HISTORY β
COBOL, the language, may well be older than the reader. π No shade, it's just true.
To the author's knowledge, free COBOL compilers first began to appear in 2000. Around that time an earlier COBOL for GCC project β cobolforgcc: https://cobolforgcc.sourceforge.net/ β met with some success, but was never officially merged into GCC. Almost iconic. Almost.
This compiler, gcobol, was begun by COBOLworx: https://www.cobolworx.com/ in the fall of 2021. The project announced a complete implementation of the core language features in December 2022. Main character energy from day one. π₯
π AUTHORS π
- James K. Lowden (
jklowden@cobolworx.com) is responsible for the parser. - Robert Dubner (
rdubner@cobolworx.com) is responsible for producing the GIMPLE tree, which is input to the GCC back-end.
Two icons. One compiler. The way that they split responsibilities?? Obsessed. π
π CAVEATS π
Read this part, bestie. It's not a jump scare but it is important.
gcobolhas been tested only on x64 and Apple M1 processors running Linux in 64-bit mode. So like, don't come for it on your weird architecture and act surprised. π«- The I/O support has not been extensively tested, and does not implement or emulate many features related to VSAM and other mainframe subsystems. While
LINE-SEQUENTIALfiles are ordinary text files that can be manipulated with standard utilities,INDEXEDandRELATIVEfiles produced bygcobolare not compatible with that of any other COBOL compiler. Enhancements to the I/O support will be readily available to the paying customer. πΈ
And that's the whole page, bestie!! This one came from the Linux source, dated February 2025, and it's GCOBOL(1) β read it, love it, compile something weird with it. Slay. πβ¨π¦
π¦ where this page comes from
- arch rolling: gcc-gcobol 16.2.1+r23+gd564253eb6c8-1 Β· GPL-3.0-or-later WITH GCC-exception-3.1 AND GFDL-1.3-or-later
- fedora 44: gcc-gcobol 16.2.1-2.fc44
- fedora 44: gcc-gcobol 16.2.1-3.fc44 Β· GPL-3.0-or-later AND LGPL-3.0-or-later AND (GPL-3.0-or-later WITH GCC-exception-3.1) AND (GPL-3.0-or-later WITH Texinfo-exception) AND (LGPL-2.1-or-later WITH GCC-exception-2.0) AND (GPL-2.0-or-later WITH GCC-exception-2.0) AND (GPL-2.0-or-later WITH GNU-compiler-exception) AND BSL-1.0 AND GFDL-1.3-or-later AND Linux-man-pages-copyleft-2-para AND SunPro AND BSD-1-Clause AND BSD-2-Clause AND BSD-2-Clause-Views AND BSD-3-Clause AND BSD-4-Clause AND BSD-Source-Code AND Zlib AND MIT AND Apache-2.0 AND (Apache-2.0 WITH LLVM-Exception) AND ZPL-2.1 AND ISC AND LicenseRef-Fedora-Public-Domain AND HP-1986 AND curl AND Martin-Birgmeier AND HPND-Markus-Kuhn AND dtoa AND SMLNJ AND AMD-newlib AND OAR AND HPND-merchantability-variant AND HPND-Intel
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms